Browse Source

cutelyst: Update to newer version, add async SQL, use Cutelee templating (#6020)

* cutelyst: Update to newer version, add async SQL, use Cutelee templating

* cutelyst: remove nginx tests

* cutelyst: include id column on updates test
Daniel Nicoletti 4 years ago
parent
commit
5c7e675537
30 changed files with 337 additions and 347 deletions
  1. 38 155
      frameworks/C++/cutelyst/benchmark_config.json
  2. 16 24
      frameworks/C++/cutelyst/build.sh
  3. 1 1
      frameworks/C++/cutelyst/cutelyst-nginx-my.dockerfile
  4. 1 1
      frameworks/C++/cutelyst/cutelyst-nginx-pg.dockerfile
  5. 1 1
      frameworks/C++/cutelyst/cutelyst-nginx.dockerfile
  6. 3 4
      frameworks/C++/cutelyst/cutelyst-pf-apg.dockerfile
  7. 0 41
      frameworks/C++/cutelyst/cutelyst-pf-my-nodelay.dockerfile
  8. 1 1
      frameworks/C++/cutelyst/cutelyst-pf-my.dockerfile
  9. 0 38
      frameworks/C++/cutelyst/cutelyst-pf-nodelay.dockerfile
  10. 1 1
      frameworks/C++/cutelyst/cutelyst-pf-pg.dockerfile
  11. 3 4
      frameworks/C++/cutelyst/cutelyst-t-apg-cutelee.dockerfile
  12. 3 4
      frameworks/C++/cutelyst/cutelyst-thread-apg.dockerfile
  13. 1 1
      frameworks/C++/cutelyst/cutelyst-thread-my-cutelee.dockerfile
  14. 1 1
      frameworks/C++/cutelyst/cutelyst-thread-my.dockerfile
  15. 0 38
      frameworks/C++/cutelyst/cutelyst-thread-nodelay.dockerfile
  16. 1 1
      frameworks/C++/cutelyst/cutelyst-thread-pg-cutelee.dockerfile
  17. 1 1
      frameworks/C++/cutelyst/cutelyst-thread-pg.dockerfile
  18. 1 1
      frameworks/C++/cutelyst/cutelyst-thread.dockerfile
  19. 1 1
      frameworks/C++/cutelyst/cutelyst.dockerfile
  20. 30 14
      frameworks/C++/cutelyst/src/CMakeLists.txt
  21. 12 2
      frameworks/C++/cutelyst/src/cutelyst-benchmarks.cpp
  22. 45 0
      frameworks/C++/cutelyst/src/databaseupdatestest.cpp
  23. 3 0
      frameworks/C++/cutelyst/src/databaseupdatestest.h
  24. 70 6
      frameworks/C++/cutelyst/src/fortunetest.cpp
  25. 15 6
      frameworks/C++/cutelyst/src/fortunetest.h
  26. 17 0
      frameworks/C++/cutelyst/src/main.cpp
  27. 40 0
      frameworks/C++/cutelyst/src/multipledatabasequeriestest.cpp
  28. 3 0
      frameworks/C++/cutelyst/src/multipledatabasequeriestest.h
  29. 25 0
      frameworks/C++/cutelyst/src/singledatabasequerytest.cpp
  30. 3 0
      frameworks/C++/cutelyst/src/singledatabasequerytest.h

+ 38 - 155
frameworks/C++/cutelyst/benchmark_config.json

@@ -19,11 +19,11 @@
                 "notes": "",
                 "versus": ""
             },
-            "pf-pg": {
-                "db_url": "/db_postgres",
-                "query_url": "/query_postgres?queries=",
-                "update_url": "/updates_postgres?queries=",
-                "fortune_url": "/fortunes_raw_postgres",
+            "pf-apg": {
+                "db_url": "/dbp",
+                "query_url": "/queriesp?queries=",
+                "update_url": "/updatep?queries=",
+                "fortune_url": "/fortunes_raw_p",
                 "port": 8080,
                 "approach": "Realistic",
                 "classification": "Fullstack",
@@ -35,49 +35,11 @@
                 "webserver": "None",
                 "os": "Linux",
                 "database_os": "Linux",
-                "display_name": "cutelyst-pf-pg",
-                "notes": "",
-                "versus": ""
-            },
-            "pf-my": {
-                "db_url": "/db_mysql",
-                "query_url": "/query_mysql?queries=",
-                "update_url": "/updates_mysql?queries=",
-                "fortune_url": "/fortunes_raw_mysql",
-                "port": 8080,
-                "approach": "Realistic",
-                "classification": "Fullstack",
-                "database": "MySQL",
-                "framework": "cutelyst",
-                "language": "C++",
-                "orm": "Raw",
-                "platform": "CutelystWSGI",
-                "webserver": "None",
-                "os": "Linux",
-                "database_os": "Linux",
-                "display_name": "cutelyst-pf-my",
+                "display_name": "cutelyst-pf-apg",
                 "notes": "",
                 "versus": ""
             },
-            "thread": {
-                "json_url": "/json",
-                "plaintext_url": "/plaintext",
-                "port": 8080,
-                "approach": "Realistic",
-                "classification": "Fullstack",
-                "database": "None",
-                "framework": "cutelyst",
-                "language": "C++",
-                "orm": "Raw",
-                "platform": "CutelystWSGI",
-                "webserver": "None",
-                "os": "Linux",
-                "database_os": "Linux",
-                "display_name": "cutelyst-thr",
-                "notes": "",
-                "versus": ""
-            },
-            "thread-pg": {
+            "pf-pg": {
                 "db_url": "/db_postgres",
                 "query_url": "/query_postgres?queries=",
                 "update_url": "/updates_postgres?queries=",
@@ -93,28 +55,11 @@
                 "webserver": "None",
                 "os": "Linux",
                 "database_os": "Linux",
-                "display_name": "cutelyst-thr-pg-raw",
-                "notes": "",
-                "versus": ""
-            },
-            "thread-pg-grantlee": {
-                "fortune_url": "/fortunes_grantlee_postgres",
-                "port": 8080,
-                "approach": "Realistic",
-                "classification": "Fullstack",
-                "database": "Postgres",
-                "framework": "cutelyst",
-                "language": "C++",
-                "orm": "Raw",
-                "platform": "CutelystWSGI",
-                "webserver": "None",
-                "os": "Linux",
-                "database_os": "Linux",
-                "display_name": "cutelyst-thr-pg-grantlee",
+                "display_name": "cutelyst-pf-pg",
                 "notes": "",
                 "versus": ""
             },
-            "thread-my": {
+            "pf-my": {
                 "db_url": "/db_mysql",
                 "query_url": "/query_mysql?queries=",
                 "update_url": "/updates_mysql?queries=",
@@ -130,16 +75,17 @@
                 "webserver": "None",
                 "os": "Linux",
                 "database_os": "Linux",
-                "display_name": "cutelyst-thr-my-raw",
+                "display_name": "cutelyst-pf-my",
                 "notes": "",
                 "versus": ""
             },
-            "thread-my-grantlee": {
-                "fortune_url": "/fortunes_grantlee_mysql",
+            "thread": {
+                "json_url": "/json",
+                "plaintext_url": "/plaintext",
                 "port": 8080,
                 "approach": "Realistic",
                 "classification": "Fullstack",
-                "database": "MySQL",
+                "database": "None",
                 "framework": "cutelyst",
                 "language": "C++",
                 "orm": "Raw",
@@ -147,17 +93,19 @@
                 "webserver": "None",
                 "os": "Linux",
                 "database_os": "Linux",
-                "display_name": "cutelyst-thr-my-grantlee",
+                "display_name": "cutelyst-thr",
                 "notes": "",
                 "versus": ""
             },
-            "pf-nodelay": {
-                "json_url": "/json",
-                "plaintext_url": "/plaintext",
+            "thread-apg": {
+                "db_url": "/dbp",
+                "query_url": "/queriesp?queries=",
+                "update_url": "/updatep?queries=",
+                "fortune_url": "/fortunes_raw_p",
                 "port": 8080,
                 "approach": "Realistic",
                 "classification": "Fullstack",
-                "database": "None",
+                "database": "Postgres",
                 "framework": "cutelyst",
                 "language": "C++",
                 "orm": "Raw",
@@ -165,11 +113,11 @@
                 "webserver": "None",
                 "os": "Linux",
                 "database_os": "Linux",
-                "display_name": "cutelyst-pf-nodelay",
+                "display_name": "cutelyst-thr-apg",
                 "notes": "",
                 "versus": ""
             },
-            "pf-pg-nodelay": {
+            "thread-pg": {
                 "db_url": "/db_postgres",
                 "query_url": "/query_postgres?queries=",
                 "update_url": "/updates_postgres?queries=",
@@ -185,37 +133,16 @@
                 "webserver": "None",
                 "os": "Linux",
                 "database_os": "Linux",
-                "display_name": "cutelyst-pf-pg-nodelay",
-                "notes": "",
-                "versus": ""
-            },
-            "pf-my-nodelay": {
-                "db_url": "/db_mysql",
-                "query_url": "/query_mysql?queries=",
-                "update_url": "/updates_mysql?queries=",
-                "fortune_url": "/fortunes_raw_mysql",
-                "port": 8080,
-                "approach": "Realistic",
-                "classification": "Fullstack",
-                "database": "MySQL",
-                "framework": "cutelyst",
-                "language": "C++",
-                "orm": "Raw",
-                "platform": "CutelystWSGI",
-                "webserver": "None",
-                "os": "Linux",
-                "database_os": "Linux",
-                "display_name": "cutelyst-pf-my-nodelay",
+                "display_name": "cutelyst-thr-pg-raw",
                 "notes": "",
                 "versus": ""
             },
-            "thread-nodelay": {
-                "json_url": "/json",
-                "plaintext_url": "/plaintext",
+            "thread-pg-cutelee": {
+                "fortune_url": "/fortunes_cutelee_postgres",
                 "port": 8080,
                 "approach": "Realistic",
                 "classification": "Fullstack",
-                "database": "None",
+                "database": "Postgres",
                 "framework": "cutelyst",
                 "language": "C++",
                 "orm": "Raw",
@@ -223,15 +150,12 @@
                 "webserver": "None",
                 "os": "Linux",
                 "database_os": "Linux",
-                "display_name": "cutelyst-thr-nodelay",
+                "display_name": "cutelyst-thr-pg-cutelee",
                 "notes": "",
                 "versus": ""
             },
-            "thread-pg-nodelay": {
-                "db_url": "/db_postgres",
-                "query_url": "/query_postgres?queries=",
-                "update_url": "/updates_postgres?queries=",
-                "fortune_url": "/fortunes_raw_postgres",
+            "t-apg-cutelee": {
+                "fortune_url": "/fortunes_c_p",
                 "port": 8080,
                 "approach": "Realistic",
                 "classification": "Fullstack",
@@ -243,11 +167,11 @@
                 "webserver": "None",
                 "os": "Linux",
                 "database_os": "Linux",
-                "display_name": "cutelyst-thr-pg-nodelay",
+                "display_name": "cutelyst-t-apg-cutelee",
                 "notes": "",
                 "versus": ""
             },
-            "thread-my-nodelay": {
+            "thread-my": {
                 "db_url": "/db_mysql",
                 "query_url": "/query_mysql?queries=",
                 "update_url": "/updates_mysql?queries=",
@@ -263,53 +187,12 @@
                 "webserver": "None",
                 "os": "Linux",
                 "database_os": "Linux",
-                "display_name": "cutelyst-thr-my-nodelay",
-                "notes": "",
-                "versus": ""
-            },
-            "nginx": {
-                "json_url": "/json",
-                "plaintext_url": "/plaintext",
-                "port": 8080,
-                "approach": "Realistic",
-                "classification": "Fullstack",
-                "database": "None",
-                "framework": "cutelyst",
-                "language": "C++",
-                "orm": "Raw",
-                "platform": "uWSGI",
-                "webserver": "nginx",
-                "os": "Linux",
-                "database_os": "Linux",
-                "display_name": "cutelyst-uwsgi-ngx",
-                "notes": "",
-                "versus": ""
-            },
-            "nginx-pg": {
-                "db_url": "/db_postgres",
-                "query_url": "/query_postgres?queries=",
-                "update_url": "/updates_postgres?queries=",
-                "fortune_url": "/fortunes_raw_postgres",
-                "port": 8080,
-                "approach": "Realistic",
-                "classification": "Fullstack",
-                "database": "Postgres",
-                "framework": "cutelyst",
-                "language": "C++",
-                "orm": "Raw",
-                "platform": "uWSGI",
-                "webserver": "nginx",
-                "os": "Linux",
-                "database_os": "Linux",
-                "display_name": "cutelyst-uwsgi-ngx-pg-raw",
+                "display_name": "cutelyst-thr-my-raw",
                 "notes": "",
                 "versus": ""
             },
-            "nginx-my": {
-                "db_url": "/db_mysql",
-                "query_url": "/query_mysql?queries=",
-                "update_url": "/updates_mysql?queries=",
-                "fortune_url": "/fortunes_raw_mysql",
+            "thread-my-cutelee": {
+                "fortune_url": "/fortunes_cutelee_mysql",
                 "port": 8080,
                 "approach": "Realistic",
                 "classification": "Fullstack",
@@ -317,11 +200,11 @@
                 "framework": "cutelyst",
                 "language": "C++",
                 "orm": "Raw",
-                "platform": "uWSGI",
-                "webserver": "nginx",
+                "platform": "CutelystWSGI",
+                "webserver": "None",
                 "os": "Linux",
                 "database_os": "Linux",
-                "display_name": "cutelyst-uwsgi-ngx-my-raw",
+                "display_name": "cutelyst-thr-my-cutelee",
                 "notes": "",
                 "versus": ""
             }

+ 16 - 24
frameworks/C++/cutelyst/build.sh

@@ -1,35 +1,27 @@
 #!/bin/bash
 
-export CUTELYST_VER=2.4.1
+export ASQL_VER=0.15.0
+export CUTELEE_VER=5.3.0
+export CUTELYST_VER=2.12.90
 
-apt-get update -qq && \
-    apt-get install -yqq --no-install-recommends \
+apt update -qq && \
+    apt install -yqq --no-install-recommends \
     cmake \
     pkg-config \
-    clearsilver-dev \
-    libgrantlee5-dev \
-    libjemalloc-dev \
+    qtbase5-dev \
     libqt5sql5-mysql \
     libqt5sql5-psql \
-    uwsgi \
-    uuid-dev \
-    libcap-dev \
-    libssl-dev \
-    libzmq3-dev \
-    libpcre3-dev \
-    zlib1g-dev \
-    nginx
+    qtdeclarative5-dev \
+    postgresql-server-dev-all
 
-wget -q https://github.com/cutelyst/cutelyst/archive/v$CUTELYST_VER.tar.gz -O cutelyst-$CUTELYST_VER.tar.gz && \
-    tar zxf cutelyst-$CUTELYST_VER.tar.gz && \
-    cd cutelyst-$CUTELYST_VER && mkdir build && cd build && \
-    cmake .. \
-    -DCMAKE_BUILD_TYPE=Release \
-    -DCMAKE_INSTALL_PREFIX=/usr \
-    -DPLUGIN_UWSGI=on \
-    -DPLUGIN_VIEW_GRANTLEE=on \
-    -DUSE_JEMALLOC=on && \
-    make && make install
+wget -q https://github.com/cutelyst/cutelee/releases/download/v${CUTELEE_VER}/cutelee5_${CUTELEE_VER}_amd64.deb && \
+    apt install -yqq ./cutelee5_${CUTELEE_VER}_amd64.deb
+
+wget -q https://github.com/cutelyst/asql/releases/download/v${ASQL_VER}/libasql_${ASQL_VER}_amd64.deb && \
+    apt install -yqq ./libasql_${ASQL_VER}_amd64.deb
+
+wget -q https://github.com/cutelyst/cutelyst/releases/download/v${CUTELYST_VER}/cutelyst_${CUTELYST_VER}_amd64.deb && \
+    apt install -yqq ./cutelyst_${CUTELYST_VER}_amd64.deb
 
 cd ${TROOT} && \
     mkdir -p build && \

+ 1 - 1
frameworks/C++/cutelyst/cutelyst-nginx-my.dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:18.04
+FROM ubuntu:20.04
 
 RUN apt-get update -qq && \
     apt-get install -yqq locales wget build-essential

+ 1 - 1
frameworks/C++/cutelyst/cutelyst-nginx-pg.dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:18.04
+FROM ubuntu:20.04
 
 RUN apt-get update -qq && \
     apt-get install -yqq locales wget build-essential

+ 1 - 1
frameworks/C++/cutelyst/cutelyst-nginx.dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:18.04
+FROM ubuntu:20.04
 
 RUN apt-get update -qq && \
     apt-get install -yqq locales wget build-essential

+ 3 - 4
frameworks/C++/cutelyst/cutelyst-pf-pg-nodelay.dockerfile → frameworks/C++/cutelyst/cutelyst-pf-apg.dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:18.04
+FROM ubuntu:20.04
 
 RUN apt-get update -qq && \
     apt-get install -yqq locales wget build-essential
@@ -26,7 +26,7 @@ RUN sed -i "s|DatabaseHostName=.*|DatabaseHostName=tfb-database|g" /cutelyst_soc
 
 ENV C_THREADS 1
 ENV CPU_AFFINITY 1
-ENV DRIVER QPSQL
+ENV DRIVER postgres
 
 RUN sed -i "s|Driver=.*|Driver=${DRIVER}|g" /cutelyst.ini
 
@@ -37,5 +37,4 @@ CMD cutelyst-wsgi2 \
     --threads=${C_THREADS} \
     --cpu-affinity=${CPU_AFFINITY} \
     --socket-timeout 0 \
-    --reuse-port \
-    --tcp-nodelay
+    --reuse-port

+ 0 - 41
frameworks/C++/cutelyst/cutelyst-pf-my-nodelay.dockerfile

@@ -1,41 +0,0 @@
-FROM ubuntu:18.04
-
-RUN apt-get update -qq && \
-    apt-get install -yqq locales wget build-essential
-
-RUN locale-gen en_US.UTF-8
-ENV LANG en_US.UTF-8
-ENV LANGUAGE en_US:en
-ENV LC_ALL en_US.UTF-8
-ENV DEBIAN_FRONTEND noninteractive
-
-ENV TROOT /cutelyst-benchmark-app
-ENV CUTELYST_APP ${TROOT}/build/libcutelyst_benchmarks.so
-
-COPY src ${TROOT}/
-
-COPY build.sh .
-RUN ./build.sh
-
-COPY config/config.ini /cutelyst.ini
-COPY config/config_socket.ini /cutelyst_socket.ini
-COPY nginx.conf /nginx.conf
-
-RUN sed -i "s|DatabaseHostName=.*|DatabaseHostName=tfb-database|g" /cutelyst.ini
-RUN sed -i "s|DatabaseHostName=.*|DatabaseHostName=tfb-database|g" /cutelyst_socket.ini
-
-ENV C_THREADS 1
-ENV CPU_AFFINITY 1
-ENV DRIVER QMYSQL
-
-RUN sed -i "s|Driver=.*|Driver=${DRIVER}|g" /cutelyst.ini
-
-CMD cutelyst-wsgi2 \
-    --ini /cutelyst.ini:uwsgi \
-    --application ${CUTELYST_APP} \
-    --processes=$(nproc) \
-    --threads=${C_THREADS} \
-    --cpu-affinity=${CPU_AFFINITY} \
-    --socket-timeout 0 \
-    --reuse-port \
-    --tcp-nodelay

+ 1 - 1
frameworks/C++/cutelyst/cutelyst-pf-my.dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:18.04
+FROM ubuntu:20.04
 
 RUN apt-get update -qq && \
     apt-get install -yqq locales wget build-essential

+ 0 - 38
frameworks/C++/cutelyst/cutelyst-pf-nodelay.dockerfile

@@ -1,38 +0,0 @@
-FROM ubuntu:18.04
-
-RUN apt-get update -qq && \
-    apt-get install -yqq locales wget build-essential
-
-RUN locale-gen en_US.UTF-8
-ENV LANG en_US.UTF-8
-ENV LANGUAGE en_US:en
-ENV LC_ALL en_US.UTF-8
-ENV DEBIAN_FRONTEND noninteractive
-
-ENV TROOT /cutelyst-benchmark-app
-ENV CUTELYST_APP ${TROOT}/build/libcutelyst_benchmarks.so
-
-COPY src ${TROOT}/
-
-COPY build.sh .
-RUN ./build.sh
-
-COPY config/config.ini /cutelyst.ini
-COPY config/config_socket.ini /cutelyst_socket.ini
-COPY nginx.conf /nginx.conf
-
-RUN sed -i "s|DatabaseHostName=.*|DatabaseHostName=tfb-database|g" /cutelyst.ini
-RUN sed -i "s|DatabaseHostName=.*|DatabaseHostName=tfb-database|g" /cutelyst_socket.ini
-
-ENV C_THREADS 1
-ENV CPU_AFFINITY 2
-
-CMD cutelyst-wsgi2 \
-    --ini /cutelyst.ini:uwsgi \
-    --application ${CUTELYST_APP} \
-    --processes=$(( ($(nproc) + 1) / 2 )) \
-    --threads=${C_THREADS} \
-    --cpu-affinity=${CPU_AFFINITY} \
-    --socket-timeout 0 \
-    --reuse-port \
-    --tcp-nodelay

+ 1 - 1
frameworks/C++/cutelyst/cutelyst-pf-pg.dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:18.04
+FROM ubuntu:20.04
 
 RUN apt-get update -qq && \
     apt-get install -yqq locales wget build-essential

+ 3 - 4
frameworks/C++/cutelyst/cutelyst-thread-pg-nodelay.dockerfile → frameworks/C++/cutelyst/cutelyst-t-apg-cutelee.dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:18.04
+FROM ubuntu:20.04
 
 RUN apt-get update -qq && \
     apt-get install -yqq locales wget build-essential
@@ -26,7 +26,7 @@ RUN sed -i "s|DatabaseHostName=.*|DatabaseHostName=tfb-database|g" /cutelyst_soc
 
 ENV C_PROCESSES 1
 ENV CPU_AFFINITY 1
-ENV DRIVER QPSQL
+ENV DRIVER postgres
 
 RUN sed -i "s|Driver=.*|Driver=${DRIVER}|g" /cutelyst.ini
 
@@ -37,5 +37,4 @@ CMD cutelyst-wsgi2 \
     --threads=$(nproc) \
     --cpu-affinity=${CPU_AFFINITY} \
     --socket-timeout 0 \
-    --reuse-port \
-    --tcp-nodelay
+    --reuse-port

+ 3 - 4
frameworks/C++/cutelyst/cutelyst-thread-my-nodelay.dockerfile → frameworks/C++/cutelyst/cutelyst-thread-apg.dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:18.04
+FROM ubuntu:20.04
 
 RUN apt-get update -qq && \
     apt-get install -yqq locales wget build-essential
@@ -26,7 +26,7 @@ RUN sed -i "s|DatabaseHostName=.*|DatabaseHostName=tfb-database|g" /cutelyst_soc
 
 ENV C_PROCESSES 1
 ENV CPU_AFFINITY 1
-ENV DRIVER QMYSQL
+ENV DRIVER postgres
 
 RUN sed -i "s|Driver=.*|Driver=${DRIVER}|g" /cutelyst.ini
 
@@ -37,5 +37,4 @@ CMD cutelyst-wsgi2 \
     --threads=$(nproc) \
     --cpu-affinity=${CPU_AFFINITY} \
     --socket-timeout 0 \
-    --reuse-port \
-    --tcp-nodelay
+    --reuse-port

+ 1 - 1
frameworks/C++/cutelyst/cutelyst-thread-my-grantlee.dockerfile → frameworks/C++/cutelyst/cutelyst-thread-my-cutelee.dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:18.04
+FROM ubuntu:20.04
 
 RUN apt-get update -qq && \
     apt-get install -yqq locales wget build-essential

+ 1 - 1
frameworks/C++/cutelyst/cutelyst-thread-my.dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:18.04
+FROM ubuntu:20.04
 
 RUN apt-get update -qq && \
     apt-get install -yqq locales wget build-essential

+ 0 - 38
frameworks/C++/cutelyst/cutelyst-thread-nodelay.dockerfile

@@ -1,38 +0,0 @@
-FROM ubuntu:18.04
-
-RUN apt-get update -qq && \
-    apt-get install -yqq locales wget build-essential
-
-RUN locale-gen en_US.UTF-8
-ENV LANG en_US.UTF-8
-ENV LANGUAGE en_US:en
-ENV LC_ALL en_US.UTF-8
-ENV DEBIAN_FRONTEND noninteractive
-
-ENV TROOT /cutelyst-benchmark-app
-ENV CUTELYST_APP ${TROOT}/build/libcutelyst_benchmarks.so
-
-COPY src ${TROOT}/
-
-COPY build.sh .
-RUN ./build.sh
-
-COPY config/config.ini /cutelyst.ini
-COPY config/config_socket.ini /cutelyst_socket.ini
-COPY nginx.conf /nginx.conf
-
-RUN sed -i "s|DatabaseHostName=.*|DatabaseHostName=tfb-database|g" /cutelyst.ini
-RUN sed -i "s|DatabaseHostName=.*|DatabaseHostName=tfb-database|g" /cutelyst_socket.ini
-
-ENV C_PROCESSES 1
-ENV CPU_AFFINITY 2
-
-CMD cutelyst-wsgi2 \
-    --ini /cutelyst.ini:uwsgi \
-    --application ${CUTELYST_APP} \
-    --processes=${C_PROCESSES} \
-    --threads=$(nproc) \
-    --cpu-affinity=${CPU_AFFINITY} \
-    --socket-timeout 0 \
-    --reuse-port \
-    --tcp-nodelay

+ 1 - 1
frameworks/C++/cutelyst/cutelyst-thread-pg-grantlee.dockerfile → frameworks/C++/cutelyst/cutelyst-thread-pg-cutelee.dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:18.04
+FROM ubuntu:20.04
 
 RUN apt-get update -qq && \
     apt-get install -yqq locales wget build-essential

+ 1 - 1
frameworks/C++/cutelyst/cutelyst-thread-pg.dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:18.04
+FROM ubuntu:20.04
 
 RUN apt-get update -qq && \
     apt-get install -yqq locales wget build-essential

+ 1 - 1
frameworks/C++/cutelyst/cutelyst-thread.dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:18.04
+FROM ubuntu:20.04
 
 RUN apt-get update -qq && \
     apt-get install -yqq locales wget build-essential

+ 1 - 1
frameworks/C++/cutelyst/cutelyst.dockerfile

@@ -1,4 +1,4 @@
-FROM ubuntu:18.04
+FROM ubuntu:20.04
 
 RUN apt-get update -qq && \
     apt-get install -yqq locales wget build-essential

+ 30 - 14
frameworks/C++/cutelyst/src/CMakeLists.txt

@@ -1,12 +1,10 @@
-project(cutelyst_benchmarks)
+cmake_minimum_required(VERSION 3.6.0 FATAL_ERROR)
 
-cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
-if (POLICY CMP0043)
-  cmake_policy(SET CMP0043 NEW)
-endif()
+project(cutelyst_benchmarks LANGUAGES CXX)
 
 find_package(Qt5 5.6.0 REQUIRED COMPONENTS Core Network Sql)
-find_package(Cutelyst2Qt5 2.0.0 REQUIRED)
+find_package(ASqlQt5 0.15.0 REQUIRED)
+find_package(Cutelyst2Qt5 2.12 REQUIRED)
 
 # Auto generate moc files
 set(CMAKE_AUTOMOC ON)
@@ -18,16 +16,25 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
 set(CMAKE_CXX_STANDARD 11)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
-include_directories(
-    ${CMAKE_SOURCE_DIR}
-    ${Cutelyst2Qt5_INCLUDE_DIR}
-)
-
 file(GLOB_RECURSE TEMPLATES_SRC root/*)
-file(GLOB_RECURSE cutelyst_benchmarks_SRCS *.cpp *.h)
 
 set(cutelyst_benchmarks_SRCS
-    ${cutelyst_benchmarks_SRCS}
+    cutelyst-benchmarks.cpp
+    cutelyst-benchmarks.h
+    databaseupdatestest.cpp
+    databaseupdatestest.h
+    fortunetest.cpp
+    fortunetest.h
+    jsontest.cpp
+    jsontest.h
+    multipledatabasequeriestest.cpp
+    multipledatabasequeriestest.h
+    plaintexttest.cpp
+    plaintexttest.h
+    root.cpp
+    root.h
+    singledatabasequerytest.cpp
+    singledatabasequerytest.h
     ${TEMPLATES_SRC}
 )
 
@@ -36,11 +43,20 @@ add_library(cutelyst_benchmarks SHARED ${cutelyst_benchmarks_SRCS})
 
 # Link to Cutelyst
 target_link_libraries(cutelyst_benchmarks
+    PUBLIC
     Cutelyst::Core
     Cutelyst::Utils::Sql
-    Cutelyst::View::Grantlee
+    Cutelyst::View::Cutelee
     Qt5::Core
     Qt5::Network
     Qt5::Sql
+    ASqlQt5::Core
 )
 
+add_executable(cutelyst-benchmarks main.cpp)
+target_link_libraries(cutelyst-benchmarks
+    Cutelyst::Core
+    Cutelyst::WSGI
+    Qt5::Network
+    cutelyst_benchmarks
+)

+ 12 - 2
frameworks/C++/cutelyst/src/cutelyst-benchmarks.cpp

@@ -1,7 +1,7 @@
 #include "cutelyst-benchmarks.h"
 
 #include <Cutelyst/Plugins/Utils/Sql>
-#include <Cutelyst/Plugins/View/Grantlee/grantleeview.h>
+#include <Cutelyst/Plugins/View/Cutelee/cuteleeview.h>
 
 #include <QtSql/QSqlDatabase>
 #include <QtSql/QSqlError>
@@ -11,6 +11,8 @@
 #include <QMutexLocker>
 #include <QDir>
 
+#include <apool.h>
+
 #include "root.h"
 #include "jsontest.h"
 #include "singledatabasequerytest.h"
@@ -39,7 +41,7 @@ bool cutelyst_benchmarks::init()
         new Root(this);
     }
 
-    auto view = new GrantleeView(this);
+    auto view = new CuteleeView(this);
     view->setIncludePaths({ QString::fromLatin1(qgetenv("TROOT")), QDir::currentPath() });
     view->preloadTemplates();
 
@@ -84,6 +86,13 @@ bool cutelyst_benchmarks::postFork()
             qDebug() << "Error opening MySQL db:" << db << db.connectionName() << db.lastError().databaseText();
             return false;
         }
+    } else if (driver == QLatin1String("postgres")) {
+        QUrl uri(QStringLiteral("postgresql://benchmarkdbuser:benchmarkdbpass@server/hello_world"));
+        uri.setHost(config(QStringLiteral("DatabaseHostName")).toString());
+        qDebug() << "ASql URI:" << uri.toString();
+
+        APool::addDatabase(uri.toString());
+        APool::setDatabaseMaxIdleConnections(15);
     }
 
     qDebug() << "Connections" << QCoreApplication::applicationPid() << QThread::currentThread() << QSqlDatabase::connectionNames();
@@ -96,3 +105,4 @@ bool cutelyst_benchmarks::postFork()
     return true;
 }
 
+#include "moc_cutelyst-benchmarks.cpp"

+ 45 - 0
frameworks/C++/cutelyst/src/databaseupdatestest.cpp

@@ -2,6 +2,10 @@
 
 #include <Cutelyst/Plugins/Utils/Sql>
 
+#include <apool.h>
+#include <aresult.h>
+#include <apreparedquery.h>
+
 #include <QSqlQuery>
 
 #include <QJsonDocument>
@@ -13,6 +17,47 @@ DatabaseUpdatesTest::DatabaseUpdatesTest(QObject *parent) : Controller(parent)
 
 }
 
+void DatabaseUpdatesTest::updatep(Context *c)
+{
+    int queries = c->request()->queryParam(QStringLiteral("queries"), QStringLiteral("1")).toInt();
+    if (queries < 1) {
+        queries = 1;
+    } else if (queries > 500) {
+        queries = 500;
+    }
+
+    QJsonArray array;
+    ASync async(c);
+    static thread_local auto db = APool::database();
+    for (int i = 0; i < queries; ++i) {
+        int id = (qrand() % 10000) + 1;
+
+        int randomNumber = (qrand() % 10000) + 1;
+
+        array.append(QJsonObject{
+                         {QStringLiteral("id"), id},
+                         {QStringLiteral("randomNumber"), randomNumber}
+                     });
+
+        db.execPrepared(APreparedQueryLiteral("SELECT randomNumber, id FROM world WHERE id=$1"),
+                               {id}, [c, async] (AResult &result) {
+            if (Q_UNLIKELY(result.error() && !result.size())) {
+                c->res()->setStatus(Response::InternalServerError);
+                return;
+            }
+        }, c);
+        db.execPrepared(APreparedQueryLiteral("UPDATE world SET randomNumber=$1 WHERE id=$2"),
+                               {randomNumber, id}, [c, async] (AResult &result) {
+            if (Q_UNLIKELY(result.error() && !result.size())) {
+                c->res()->setStatus(Response::InternalServerError);
+                return;
+            }
+        }, c);
+    }
+
+    c->response()->setJsonArrayBody(array);
+}
+
 void DatabaseUpdatesTest::updates_postgres(Context *c)
 {
     QSqlQuery query = CPreparedSqlQueryThreadForDB(

+ 3 - 0
frameworks/C++/cutelyst/src/databaseupdatestest.h

@@ -13,6 +13,9 @@ class DatabaseUpdatesTest : public Controller
 public:
     explicit DatabaseUpdatesTest(QObject *parent = 0);
 
+    C_ATTR(updatep, :Local :AutoArgs)
+    void updatep(Context *c);
+
     C_ATTR(updates_postgres, :Local :AutoArgs)
     void updates_postgres(Context *c);
 

+ 70 - 6
frameworks/C++/cutelyst/src/fortunetest.cpp

@@ -3,6 +3,10 @@
 #include <Cutelyst/Plugins/Utils/Sql>
 #include <Cutelyst/View>
 
+#include <apool.h>
+#include <aresult.h>
+#include <apreparedquery.h>
+
 #include <QSqlQuery>
 
 FortuneTest::FortuneTest(QObject *parent) : Controller(parent)
@@ -10,6 +14,32 @@ FortuneTest::FortuneTest(QObject *parent) : Controller(parent)
 
 }
 
+void FortuneTest::fortunes_raw_p(Context *c)
+{
+    ASync async(c);
+    static thread_local auto db = APool::database();
+    db.execPrepared(APreparedQueryLiteral("SELECT id, message FROM fortune"), [c, async, this] (AResult &result) {
+        if (Q_UNLIKELY(result.error() && !result.size())) {
+            c->res()->setStatus(Response::InternalServerError);
+            return;
+        }
+
+        FortuneList fortunes;
+        auto it = result.begin();
+        while (it != result.end()) {
+            fortunes.push_back({it[0].toInt(), it[1].toString()});
+            ++it;
+        }
+        fortunes.push_back({0, QStringLiteral("Additional fortune added at request time.")});
+
+        std::sort(fortunes.begin(), fortunes.end(), [] (const Fortune &a1, const Fortune &a2) {
+            return a1.message < a2.message;
+        });
+
+        renderRaw(c, fortunes);
+    }, c);
+}
+
 void FortuneTest::fortunes_raw_postgres(Context *c)
 {
     QSqlQuery query = CPreparedSqlQueryThreadForDB(
@@ -28,7 +58,41 @@ void FortuneTest::fortunes_raw_mysql(Context *c)
     renderRaw(c, fortunes);
 }
 
-void FortuneTest::fortunes_grantlee_postgres(Context *c)
+void FortuneTest::fortunes_c_p(Context *c)
+{
+    ASync async(c);
+    static thread_local auto db = APool::database();
+    db.execPrepared(APreparedQueryLiteral("SELECT id, message FROM fortune"), [c, async] (AResult &result) {
+        if (Q_UNLIKELY(result.error() && !result.size())) {
+            c->res()->setStatus(Response::InternalServerError);
+            return;
+        }
+
+        QVariantList fortunes;
+        auto it = result.begin();
+        while (it != result.end()) {
+            fortunes.append(QVariant::fromValue(QVariantList{
+                                                    {it[0].toInt(), it[1].toString()},
+                                                }));
+            ++it;
+        }
+
+        fortunes.append(QVariant::fromValue(QVariantList{
+                            {0, QStringLiteral("Additional fortune added at request time.")},
+                        }));
+        std::sort(fortunes.begin(), fortunes.end(), [] (const QVariant &a1, const QVariant &a2) {
+            return a1.toList()[1].toString() < a2.toList()[1].toString();
+        });
+
+        c->setStash(QStringLiteral("template"), QStringLiteral("fortunes.html"));
+        c->setStash(QStringLiteral("fortunes"), fortunes);
+        static thread_local View *view = c->view();
+        view->execute(c);
+        c->response()->setContentType(QStringLiteral("text/html; charset=UTF-8"));
+    }, c);
+}
+
+void FortuneTest::fortunes_cutelee_postgres(Context *c)
 {
     QSqlQuery query = CPreparedSqlQueryThreadForDB(
                 QLatin1String("SELECT id, message FROM fortune"),
@@ -49,7 +113,7 @@ void FortuneTest::fortunes_grantlee_postgres(Context *c)
     }
 }
 
-void FortuneTest::fortunes_grantlee_mysql(Context *c)
+void FortuneTest::fortunes_cutelee_mysql(Context *c)
 {
     QSqlQuery query = CPreparedSqlQueryThreadForDB(
                 QLatin1String("SELECT id, message FROM fortune"),
@@ -85,13 +149,13 @@ FortuneList FortuneTest::processQuery(Context *c, QSqlQuery &query)
     fortunes.push_back({0, QStringLiteral("Additional fortune added at request time.")});
 
     std::sort(fortunes.begin(), fortunes.end(), [] (const Fortune &a1, const Fortune &a2) {
-        return a1.second < a2.second;
+        return a1.message < a2.message;
     });
 
     return fortunes;
 }
 
-void FortuneTest::renderRaw(Context *c, const FortuneList &fortunes)
+void FortuneTest::renderRaw(Context *c, const FortuneList &fortunes) const
 {
     QString out;
     out.append(QStringLiteral("<!DOCTYPE html>"
@@ -104,9 +168,9 @@ void FortuneTest::renderRaw(Context *c, const FortuneList &fortunes)
 
     for (const Fortune &fortune : fortunes) {
         out.append(QStringLiteral("<tr><td>"))
-                .append(QString::number(fortune.first))
+                .append(QString::number(fortune.id))
                 .append(QStringLiteral("</td><td>"))
-                .append(fortune.second.toHtmlEscaped())
+                .append(fortune.message.toHtmlEscaped())
                 .append(QStringLiteral("</td></tr>"));
     }
 

+ 15 - 6
frameworks/C++/cutelyst/src/fortunetest.h

@@ -5,7 +5,10 @@
 
 using namespace Cutelyst;
 
-typedef std::pair<int, QString> Fortune;
+typedef struct {
+    int id;
+    QString message;
+} Fortune;
 typedef std::vector<Fortune> FortuneList;
 
 class QSqlQuery;
@@ -16,21 +19,27 @@ class FortuneTest : public Controller
 public:
     explicit FortuneTest(QObject *parent = 0);
 
+    C_ATTR(fortunes_raw_p, :Local :AutoArgs)
+    void fortunes_raw_p(Context *c);
+
     C_ATTR(fortunes_raw_postgres, :Local :AutoArgs)
     void fortunes_raw_postgres(Context *c);
 
     C_ATTR(fortunes_raw_mysql, :Local :AutoArgs)
     void fortunes_raw_mysql(Context *c);
 
-    C_ATTR(fortunes_grantlee_postgres, :Local :AutoArgs)
-    void fortunes_grantlee_postgres(Context *c);
+    C_ATTR(fortunes_c_p, :Local :AutoArgs)
+    void fortunes_c_p(Context *c);
+
+    C_ATTR(fortunes_cutelee_postgres, :Local :AutoArgs)
+    void fortunes_cutelee_postgres(Context *c);
 
-    C_ATTR(fortunes_grantlee_mysql, :Local :AutoArgs)
-    void fortunes_grantlee_mysql(Context *c);
+    C_ATTR(fortunes_cutelee_mysql, :Local :AutoArgs)
+    void fortunes_cutelee_mysql(Context *c);
 
 private:
     inline FortuneList processQuery(Context *c, QSqlQuery &query);
-    inline void renderRaw(Context *c, const FortuneList &fortunes);
+    inline void renderRaw(Context *c, const FortuneList &fortunes) const;
 };
 
 #endif // FORTUNETEST_H

+ 17 - 0
frameworks/C++/cutelyst/src/main.cpp

@@ -0,0 +1,17 @@
+#include "cutelyst-benchmarks.h"
+
+#include <QCoreApplication>
+
+#include <Cutelyst/WSGI/wsgi.h>
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication app(argc, argv);
+
+    CWSGI::WSGI wsgi;
+    wsgi.parseCommandLine(app.arguments());
+
+    auto bench = new cutelyst_benchmarks;
+
+    return wsgi.exec(bench);
+}

+ 40 - 0
frameworks/C++/cutelyst/src/multipledatabasequeriestest.cpp

@@ -2,6 +2,10 @@
 
 #include <Cutelyst/Plugins/Utils/Sql>
 
+#include <apool.h>
+#include <aresult.h>
+#include <apreparedquery.h>
+
 #include <QSqlQuery>
 
 #include <QJsonDocument>
@@ -13,6 +17,42 @@ MultipleDatabaseQueriesTest::MultipleDatabaseQueriesTest(QObject *parent) : Cont
 
 }
 
+void MultipleDatabaseQueriesTest::queriesp(Context *c)
+{
+    int queries = c->request()->queryParam(QStringLiteral("queries")).toInt();
+    if (queries < 1) {
+        queries = 1;
+    } else if (queries > 500) {
+        queries = 500;
+    }
+
+    auto array = QSharedPointer<QJsonArray>(new QJsonArray);
+    ASync async(c);
+    static thread_local auto db = APool::database();
+    for (int i = 0; i < queries; ++i) {
+        const int id = (qrand() % 10000) + 1;
+
+        db.execPrepared(APreparedQueryLiteral("SELECT id, randomNumber FROM world WHERE id=$1"),
+                               {id}, [c, async, i, queries, array] (AResult &result) {
+            if (Q_UNLIKELY(result.error() && !result.size())) {
+                c->res()->setStatus(Response::InternalServerError);
+                return;
+            }
+
+
+            auto it = result.begin();
+            array->append(QJsonObject{
+                              {QStringLiteral("id"), it[0].toInt()},
+                              {QStringLiteral("randomNumber"), it[1].toInt()}
+                          });
+
+            if (i + 1 == queries) {
+                c->response()->setJsonArrayBody(*array);
+            }
+        }, c);
+    }
+}
+
 void MultipleDatabaseQueriesTest::query_postgres(Context *c)
 {
     QSqlQuery query = CPreparedSqlQueryThreadForDB(

+ 3 - 0
frameworks/C++/cutelyst/src/multipledatabasequeriestest.h

@@ -13,6 +13,9 @@ class MultipleDatabaseQueriesTest : public Controller
 public:
     explicit MultipleDatabaseQueriesTest(QObject *parent = 0);
 
+    C_ATTR(queriesp, :Local :AutoArgs)
+    void queriesp(Context *c);
+
     C_ATTR(query_postgres, :Local :AutoArgs)
     void query_postgres(Context *c);
 

+ 25 - 0
frameworks/C++/cutelyst/src/singledatabasequerytest.cpp

@@ -2,6 +2,10 @@
 
 #include <Cutelyst/Plugins/Utils/Sql>
 
+#include <apool.h>
+#include <aresult.h>
+#include <apreparedquery.h>
+
 #include <QSqlQuery>
 
 #include <QJsonDocument>
@@ -12,6 +16,27 @@ SingleDatabaseQueryTest::SingleDatabaseQueryTest(QObject *parent) : Controller(p
 
 }
 
+void SingleDatabaseQueryTest::dbp(Context *c)
+{
+    const int id = (qrand() % 10000) + 1;
+
+    ASync async(c);
+    static thread_local auto db = APool::database();
+    db.execPrepared(APreparedQueryLiteral("SELECT id, randomNumber FROM world WHERE id=$1"),
+                           {id}, [c, async] (AResult &result) {
+        if (Q_UNLIKELY(result.error() && !result.size())) {
+            c->res()->setStatus(Response::InternalServerError);
+            return;
+        }
+
+        auto it = result.begin();
+        c->response()->setJsonObjectBody({
+                                             {QStringLiteral("id"), it[0].toInt()},
+                                             {QStringLiteral("randomNumber"), it[1].toInt()}
+                                         });
+    }, c);
+}
+
 void SingleDatabaseQueryTest::db_postgres(Context *c)
 {
     QSqlQuery query = CPreparedSqlQueryThreadForDB(

+ 3 - 0
frameworks/C++/cutelyst/src/singledatabasequerytest.h

@@ -13,6 +13,9 @@ class SingleDatabaseQueryTest : public Controller
 public:
     explicit SingleDatabaseQueryTest(QObject *parent = 0);
 
+    C_ATTR(dbp, :Local :AutoArgs)
+    void dbp(Context *c);
+
     C_ATTR(db_postgres, :Local :AutoArgs)
     void db_postgres(Context *c);