Browse Source

[cutelyst] Update to v2.13.0 and add an async update in batched mode (#6099)

* [cutelyst] Update to v2.13.0 and add an async update in batched mode

* [cutelyst] Add missing dockerfiles
Daniel Nicoletti 4 years ago
parent
commit
185df573a4

+ 34 - 0
frameworks/C++/cutelyst/benchmark_config.json

@@ -39,6 +39,23 @@
                 "notes": "",
                 "versus": ""
             },
+            "pf-apg-batch": {
+                "update_url": "/updateb?queries=",
+                "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-pf-apg",
+                "notes": "",
+                "versus": ""
+            },
             "pf-pg": {
                 "db_url": "/db_postgres",
                 "query_url": "/query_postgres?queries=",
@@ -117,6 +134,23 @@
                 "notes": "",
                 "versus": ""
             },
+            "thread-apg-batch": {
+                "update_url": "/updateb?queries=",
+                "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-apg",
+                "notes": "",
+                "versus": ""
+            },
             "thread-pg": {
                 "db_url": "/db_postgres",
                 "query_url": "/query_postgres?queries=",

+ 2 - 2
frameworks/C++/cutelyst/build.sh

@@ -1,8 +1,8 @@
 #!/bin/bash
 
-export ASQL_VER=0.18.0
+export ASQL_VER=0.19.0
 export CUTELEE_VER=5.3.0
-export CUTELYST_VER=2.12.90
+export CUTELYST_VER=2.13.0
 
 apt update -qq && \
     apt install -yqq --no-install-recommends \

+ 40 - 0
frameworks/C++/cutelyst/cutelyst-pf-apg-batch.dockerfile

@@ -0,0 +1,40 @@
+FROM ubuntu:20.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 postgres
+
+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

+ 40 - 0
frameworks/C++/cutelyst/cutelyst-thread-apg-batch.dockerfile

@@ -0,0 +1,40 @@
+FROM ubuntu:20.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 1
+ENV DRIVER postgres
+
+RUN sed -i "s|Driver=.*|Driver=${DRIVER}|g" /cutelyst.ini
+
+CMD cutelyst-wsgi2 \
+    --ini /cutelyst.ini:uwsgi \
+    --application ${CUTELYST_APP} \
+    --processes=${C_PROCESSES} \
+    --threads=$(nproc) \
+    --cpu-affinity=${CPU_AFFINITY} \
+    --socket-timeout 0 \
+    --reuse-port

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

@@ -58,6 +58,56 @@ void DatabaseUpdatesTest::updatep(Context *c)
     c->response()->setJsonArrayBody(array);
 }
 
+void DatabaseUpdatesTest::updateb(Context *c)
+{
+    int queries = c->request()->queryParam(QStringLiteral("queries"), QStringLiteral("1")).toInt();
+    if (queries < 1) {
+        queries = 1;
+    } else if (queries > 500) {
+        queries = 500;
+    }
+
+    QVariantList args;
+    QVariantList argsIds;
+
+    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;
+
+        argsIds.append(id);
+        args.append(id);
+        args.append(randomNumber);
+
+        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);
+    }
+    args.append(argsIds);
+
+    const APreparedQuery pq = getSql(queries);
+    db.execPrepared(pq, args, [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(
@@ -121,3 +171,29 @@ void DatabaseUpdatesTest::processQuery(Context *c, QSqlQuery &query, QSqlQuery &
         c->res()->setStatus(Response::InternalServerError);
     }
 }
+
+APreparedQuery DatabaseUpdatesTest::getSql(int count)
+{
+    auto iter = m_sqlMap.find(count);
+    if (iter != m_sqlMap.end())
+    {
+        return iter.value();
+    }
+    QString sql = QStringLiteral("UPDATE WORLD SET randomnumber=CASE id ");
+    sql.reserve(80 + count * 25);
+    int placeholdersCounter = 1;
+    for (int i = 0; i < count; i++) {
+        sql.append(QStringLiteral("WHEN $%1 THEN $%2 ").arg(placeholdersCounter).arg(placeholdersCounter + 1));
+        placeholdersCounter += 2;
+    }
+    sql.append(QStringLiteral("ELSE randomnumber END WHERE id IN ("));
+
+    for (int i = 0; i < count; i++) {
+        sql.append(QLatin1Char('$') + QString::number(placeholdersCounter));
+        ++placeholdersCounter;
+    }
+    sql.append(QLatin1Char(')'));
+    m_sqlMap.insert(count, sql);
+
+    return sql;
+}

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

@@ -2,6 +2,7 @@
 #define DATABASEUPDATESTEST_H
 
 #include <Cutelyst/Controller>
+#include <apreparedquery.h>
 
 using namespace Cutelyst;
 
@@ -16,6 +17,9 @@ public:
     C_ATTR(updatep, :Local :AutoArgs)
     void updatep(Context *c);
 
+    C_ATTR(updateb, :Local :AutoArgs)
+    void updateb(Context *c);
+
     C_ATTR(updates_postgres, :Local :AutoArgs)
     void updates_postgres(Context *c);
 
@@ -24,6 +28,9 @@ public:
 
 private:
     inline void processQuery(Context *c, QSqlQuery &query, QSqlQuery &updateQuery);
+    inline APreparedQuery getSql(int count);
+
+    QMap<int, APreparedQuery> m_sqlMap;
 };
 
 #endif // DATABASEUPDATESTEST_H