Browse Source

Upgrade ffead-cpp to v5.1 (#6062)

* Added M-Web-Server tests (Mumps)

* Upgrade ffead-cpp to v5.1
Improved performance of multi queries for pgsql
Added h2o backend server
Fixed issues with cached tests and added better memory implementation
Sumeet Chhetri 4 years ago
parent
commit
936694afc5
55 changed files with 1248 additions and 280 deletions
  1. 1 0
      .travis.yml
  2. 45 2
      frameworks/C++/ffead-cpp/benchmark_config.json
  3. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-apache.dockerfile
  4. 4 2
      frameworks/C++/ffead-cpp/ffead-cpp-base.dockerfile
  5. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-cinatra.dockerfile
  6. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-crystal-h2o.dockerfile
  7. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-crystal-http.dockerfile
  8. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-drogon.dockerfile
  9. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-go-fasthttp.dockerfile
  10. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-go-gnet.dockerfile
  11. 38 0
      frameworks/C++/ffead-cpp/ffead-cpp-h2o.dockerfile
  12. 3 3
      frameworks/C++/ffead-cpp/ffead-cpp-java-base.dockerfile
  13. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-java-firenio.dockerfile
  14. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-java-rapidoid.dockerfile
  15. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-java-wizzardo-http.dockerfile
  16. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-libreactor.dockerfile
  17. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-lithium.dockerfile
  18. 2 2
      frameworks/C++/ffead-cpp/ffead-cpp-mongo-raw.dockerfile
  19. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-mysql.dockerfile
  20. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-nginx.dockerfile
  21. 7 0
      frameworks/C++/ffead-cpp/ffead-cpp-postgresql-raw-async.dockerfile
  22. 2 2
      frameworks/C++/ffead-cpp/ffead-cpp-postgresql-raw.dockerfile
  23. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-postgresql.dockerfile
  24. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-rust-actix.dockerfile
  25. 3 3
      frameworks/C++/ffead-cpp/ffead-cpp-rust-base.dockerfile
  26. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-rust-hyper.dockerfile
  27. 4 4
      frameworks/C++/ffead-cpp/ffead-cpp-rust-rocket-base.dockerfile
  28. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-rust-rocket.dockerfile
  29. 3 3
      frameworks/C++/ffead-cpp/ffead-cpp-v-base.dockerfile
  30. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-v-picov.dockerfile
  31. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp-v-vweb.dockerfile
  32. 1 1
      frameworks/C++/ffead-cpp/ffead-cpp.dockerfile
  33. 15 1
      frameworks/C++/ffead-cpp/install_ffead-cpp-backends.sh
  34. 4 0
      frameworks/C++/ffead-cpp/install_ffead-cpp-dependencies.sh
  35. 6 7
      frameworks/C++/ffead-cpp/install_ffead-cpp-framework.sh
  36. 65 117
      frameworks/C++/ffead-cpp/run_ffead.sh
  37. 7 0
      frameworks/C++/ffead-cpp/te-benchmark-um-mgr/config/cachememory.xml
  38. 9 1
      frameworks/C++/ffead-cpp/te-benchmark-um-mgr/include/TeBkUmMgr.h
  39. 34 19
      frameworks/C++/ffead-cpp/te-benchmark-um-mgr/src/TeBkUmMgr.cpp
  40. 10 0
      frameworks/C++/ffead-cpp/te-benchmark-um-pq-async/CMakeLists.txt
  41. 24 0
      frameworks/C++/ffead-cpp/te-benchmark-um-pq-async/config/application.xml
  42. 7 0
      frameworks/C++/ffead-cpp/te-benchmark-um-pq-async/config/cachememory.xml
  43. 15 0
      frameworks/C++/ffead-cpp/te-benchmark-um-pq-async/config/sdorm.xml
  44. 145 0
      frameworks/C++/ffead-cpp/te-benchmark-um-pq-async/include/TeBkUmLpqAsync.h
  45. 503 0
      frameworks/C++/ffead-cpp/te-benchmark-um-pq-async/src/TeBkUmLpqAsync.cpp
  46. 17 0
      frameworks/C++/ffead-cpp/te-benchmark-um-pq-async/src/autotools/Makefile.am
  47. 13 0
      frameworks/C++/ffead-cpp/te-benchmark-um-pq-async/tpe/fortunes.tpe
  48. 7 0
      frameworks/C++/ffead-cpp/te-benchmark-um-pq/config/cachememory.xml
  49. 1 0
      frameworks/C++/ffead-cpp/te-benchmark-um-pq/config/sdorm.xml
  50. 23 2
      frameworks/C++/ffead-cpp/te-benchmark-um-pq/include/TeBkUmLpq.h
  51. 164 75
      frameworks/C++/ffead-cpp/te-benchmark-um-pq/src/TeBkUmLpq.cpp
  52. 7 0
      frameworks/C++/ffead-cpp/te-benchmark-um/config/cachememory.xml
  53. 8 2
      frameworks/C++/ffead-cpp/te-benchmark-um/include/TeBkUm.h
  54. 30 13
      frameworks/C++/ffead-cpp/te-benchmark-um/src/TeBkUm.cpp
  55. 1 1
      frameworks/C++/ffead-cpp/te-benchmark-um/src/autotools/Makefile.am

+ 1 - 0
.travis.yml

@@ -93,6 +93,7 @@ env:
     - "TESTLANG=V"
     - "TESTLANG=V"
     - "TESTLANG=Vala"
     - "TESTLANG=Vala"
     - "TESTLANG=VB"
     - "TESTLANG=VB"
+    - "TESTLANG=Mumps"
 
 
 before_script:
 before_script:
   # Runs travis_diff, printing the output to the terminal, and searches for travis-diff-continue
   # Runs travis_diff, printing the output to the terminal, and searches for travis-diff-continue

+ 45 - 2
frameworks/C++/ffead-cpp/benchmark_config.json

@@ -45,7 +45,7 @@
 			"os": "Linux",
 			"os": "Linux",
 			"database_os": "Linux",
 			"database_os": "Linux",
 			"display_name": "ffead-cpp-mongo-raw",
 			"display_name": "ffead-cpp-mongo-raw",
-			"notes": "mongodb raw redis",
+			"notes": "mongodb raw memory",
 			"versus": "",
 			"versus": "",
 			"tags": []
 			"tags": []
 		},
 		},
@@ -125,6 +125,25 @@
 			"versus": "",
 			"versus": "",
 			"tags": []
 			"tags": []
 		},
 		},
+		"h2o": {
+			"json_url": "/te-benchmark-um/json",
+			"plaintext_url": "/plaintext",
+			"port": 8080,
+			"approach": "Realistic",
+			"classification": "Fullstack",
+			"database": "None",
+			"framework": "ffead-cpp",
+			"language": "C++",
+			"orm": "None",
+			"platform": "None",
+			"webserver": "h2o",
+			"os": "Linux",
+			"database_os": "Linux",
+			"display_name": "ffead-cpp-h2o",
+			"notes": "",
+			"versus": "",
+			"tags": []
+		},
 		"crystal-h2o": {
 		"crystal-h2o": {
 			"json_url": "/te-benchmark-um/json",
 			"json_url": "/te-benchmark-um/json",
 			"plaintext_url": "/plaintext",
 			"plaintext_url": "/plaintext",
@@ -439,7 +458,31 @@
 			"os": "Linux",
 			"os": "Linux",
 			"database_os": "Linux",
 			"database_os": "Linux",
 			"display_name": "ffead-cpp-postgresql-raw",
 			"display_name": "ffead-cpp-postgresql-raw",
-			"notes": "",
+			"notes": "memory",
+			"versus": "",
+			"tags": []
+		},
+		"postgresql-raw-async": {
+			"json_url": "/te-benchmark-um-pq-async/json",
+			"plaintext_url": "/plaintext",
+			"db_url": "/te-benchmark-um-pq-async/db",
+			"query_url": "/te-benchmark-um-pq-async/queries?queries=",
+			"fortune_url": "/te-benchmark-um-pq-async/fortunes",
+			"update_url": "/te-benchmark-um-pq-async/updates?queries=",
+			"cached_query_url": "/te-benchmark-um-pq-async/cached-worlds?count=",
+			"port": 8080,
+			"approach": "Realistic",
+			"classification": "Fullstack",
+			"database": "postgres",
+			"framework": "ffead-cpp",
+			"language": "C++",
+			"orm": "Raw",
+			"platform": "None",
+			"webserver": "ffead-cpp",
+			"os": "Linux",
+			"database_os": "Linux",
+			"display_name": "ffead-cpp-postgresql-raw-async",
+			"notes": "async memory",
 			"versus": "",
 			"versus": "",
 			"tags": []
 			"tags": []
 		},
 		},

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-apache.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 4 - 2
frameworks/C++/ffead-cpp/ffead-cpp-base.dockerfile

@@ -1,13 +1,15 @@
 FROM buildpack-deps:bionic
 FROM buildpack-deps:bionic
 LABEL maintainer="Sumeet Chhetri"
 LABEL maintainer="Sumeet Chhetri"
-LABEL version="latest"
-LABEL description="Base ffead-cpp docker image with commit id - 5f62633149d832c5608c64fd4a1097fb6ebf6f5c"
+LABEL version="5.1"
+LABEL description="Base ffead-cpp docker image with commit id - master"
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
+ENV DEBUG=off
 
 
 RUN mkdir /installs
 RUN mkdir /installs
 COPY te-benchmark-um/ /installs/te-benchmark-um/
 COPY te-benchmark-um/ /installs/te-benchmark-um/
 COPY te-benchmark-um-pq/ /installs/te-benchmark-um-pq/
 COPY te-benchmark-um-pq/ /installs/te-benchmark-um-pq/
+COPY te-benchmark-um-pq-async/ /installs/te-benchmark-um-pq-async/
 COPY te-benchmark-um-mgr/ /installs/te-benchmark-um-mgr/
 COPY te-benchmark-um-mgr/ /installs/te-benchmark-um-mgr/
 
 
 WORKDIR ${IROOT}
 WORKDIR ${IROOT}

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-cinatra.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-crystal-h2o.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-crystal-http.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-drogon.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-go-fasthttp.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-go-gnet.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 38 - 0
frameworks/C++/ffead-cpp/ffead-cpp-h2o.dockerfile

@@ -0,0 +1,38 @@
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
+
+ENV IROOT=/installs
+
+RUN rm -f /usr/local/lib/libffead-* /usr/local/lib/libte_benc* /usr/local/lib/libinter.so /usr/local/lib/libdinter.so && \
+	ln -s ${IROOT}/ffead-cpp-5.0/lib/libte_benchmark_um.so /usr/local/lib/libte_benchmark_um.so && \
+	ln -s ${IROOT}/ffead-cpp-5.0/lib/libffead-modules.so /usr/local/lib/libffead-modules.so && \
+	ln -s ${IROOT}/ffead-cpp-5.0/lib/libffead-framework.so /usr/local/lib/libffead-framework.so && \
+	ln -s ${IROOT}/ffead-cpp-5.0/lib/libinter.so /usr/local/lib/libinter.so && \
+	ln -s ${IROOT}/ffead-cpp-5.0/lib/libdinter.so /usr/local/lib/libdinter.so && \
+	ldconfig
+
+WORKDIR ${IROOT}
+RUN apt-get update -y && apt-get install -y --no-install-recommends autoconf bison cmake curl file flex g++ git libssl-dev libtool libz-dev make wget \
+	 && rm -rf /var/lib/apt/lists/*
+
+ARG H2O_VERSION=v2.2.6
+
+ARG H2O_BUILD_DIR=${IROOT}/h2o-build
+ENV H2O_PREFIX /opt/h2o
+
+RUN mkdir -p "${H2O_BUILD_DIR}/build" && \
+    cd "$H2O_BUILD_DIR" && \
+    wget -qO - "https://github.com/h2o/h2o/archive/${H2O_VERSION}.tar.gz" | \
+    tar xz --strip-components=1 && \
+    cd build && \
+    cmake -DCMAKE_C_FLAGS="-flto -march=native" \
+          -DCMAKE_AR=/usr/bin/gcc-ar -DCMAKE_RANLIB=/usr/bin/gcc-ranlib .. && \
+    make -j "$(nproc)" install && \
+    cd ../.. && \
+    rm -rf "$H2O_BUILD_DIR"
+
+WORKDIR ${IROOT}/lang-server-backends/c/h2o
+RUN cmake . && make && cp h2o_app $IROOT/ && rm -rf ${IROOT}/lang-server-backends
+
+WORKDIR /
+
+CMD ./run_ffead.sh ffead-cpp-5.0 h2o

+ 3 - 3
frameworks/C++/ffead-cpp/ffead-cpp-java-base.dockerfile

@@ -1,7 +1,7 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 LABEL maintainer="Sumeet Chhetri"
 LABEL maintainer="Sumeet Chhetri"
-LABEL version="latest"
-LABEL description="Base java docker image with commit id - 5f62633149d832c5608c64fd4a1097fb6ebf6f5c"
+LABEL version="5.1"
+LABEL description="Base java docker image with master code"
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-java-firenio.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-java-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-java-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-java-rapidoid.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-java-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-java-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-java-wizzardo-http.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-java-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-java-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-libreactor.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-lithium.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 2 - 2
frameworks/C++/ffead-cpp/ffead-cpp-mongo-raw.dockerfile

@@ -1,7 +1,7 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 
 WORKDIR /
 WORKDIR /
 
 
-CMD ./run_ffead.sh ffead-cpp-5.0 emb mongo-raw redis
+CMD ./run_ffead.sh ffead-cpp-5.0 emb mongo-raw memory

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-mysql.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-nginx.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 7 - 0
frameworks/C++/ffead-cpp/ffead-cpp-postgresql-raw-async.dockerfile

@@ -0,0 +1,7 @@
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
+
+ENV IROOT=/installs
+
+WORKDIR /
+
+CMD ./run_ffead.sh ffead-cpp-5.0-sql emb postgresql-raw-async memory

+ 2 - 2
frameworks/C++/ffead-cpp/ffead-cpp-postgresql-raw.dockerfile

@@ -1,7 +1,7 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 
 WORKDIR /
 WORKDIR /
 
 
-CMD ./run_ffead.sh ffead-cpp-5.0-sql emb postgresql-raw redis
+CMD ./run_ffead.sh ffead-cpp-5.0-sql emb postgresql-raw memory

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-postgresql.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-rust-actix.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-rust-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-rust-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 3 - 3
frameworks/C++/ffead-cpp/ffead-cpp-rust-base.dockerfile

@@ -1,7 +1,7 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 LABEL maintainer="Sumeet Chhetri"
 LABEL maintainer="Sumeet Chhetri"
-LABEL version="latest"
-LABEL description="Base rust docker image with commit id - 5f62633149d832c5608c64fd4a1097fb6ebf6f5c"
+LABEL version="5.1"
+LABEL description="Base rust docker image with ffead-cpp v4.0 - commit id - master"
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-rust-hyper.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-rust-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-rust-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 4 - 4
frameworks/C++/ffead-cpp/ffead-cpp-rust-rocket-base.dockerfile

@@ -1,7 +1,7 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 LABEL maintainer="Sumeet Chhetri"
 LABEL maintainer="Sumeet Chhetri"
-LABEL version="2.0"
-LABEL description="Base rust rocket docker image with commit id - 5f62633149d832c5608c64fd4a1097fb6ebf6f5c"
+LABEL version="5.1"
+LABEL description="Base rust rocket docker image with ffead-cpp v5.0 - commit id - master"
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 
@@ -28,4 +28,4 @@ RUN mkdir -p /installs/snmalloc-0.4.2/build
 COPY --from=0 /installs/snmalloc-0.4.2/build/libsnmallocshim-1mib.so /installs/snmalloc-0.4.2/build
 COPY --from=0 /installs/snmalloc-0.4.2/build/libsnmallocshim-1mib.so /installs/snmalloc-0.4.2/build
 COPY --from=0 /usr/lib/x86_64-linux-gnu/odbc /usr/lib/x86_64-linux-gnu/odbc
 COPY --from=0 /usr/lib/x86_64-linux-gnu/odbc /usr/lib/x86_64-linux-gnu/odbc
 COPY --from=0 /usr/local/lib /usr/local/lib
 COPY --from=0 /usr/local/lib /usr/local/lib
-COPY --from=0 /run_ffead.sh /
+COPY --from=0 /run_ffead.sh /

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-rust-rocket.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-rust-rocket-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-rust-rocket-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 3 - 3
frameworks/C++/ffead-cpp/ffead-cpp-v-base.dockerfile

@@ -1,7 +1,7 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 LABEL maintainer="Sumeet Chhetri"
 LABEL maintainer="Sumeet Chhetri"
-LABEL version="latest"
-LABEL description="Base v docker image with commit id - 5f62633149d832c5608c64fd4a1097fb6ebf6f5c"
+LABEL version="5.1"
+LABEL description="Base v docker image with ffead-cpp v4.0 commit id - master"
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-v-picov.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-v-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-v-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp-v-vweb.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-v-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-v-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 1 - 1
frameworks/C++/ffead-cpp/ffead-cpp.dockerfile

@@ -1,4 +1,4 @@
-FROM sumeetchhetri/ffead-cpp-5.0-base:latest
+FROM sumeetchhetri/ffead-cpp-5.0-base:5.1
 
 
 ENV IROOT=/installs
 ENV IROOT=/installs
 
 

+ 15 - 1
frameworks/C++/ffead-cpp/install_ffead-cpp-backends.sh

@@ -4,7 +4,7 @@ cd $IROOT
 
 
 git clone https://github.com/sumeetchhetri/ffead-cpp
 git clone https://github.com/sumeetchhetri/ffead-cpp
 cd ffead-cpp
 cd ffead-cpp
-git checkout 5f62633149d832c5608c64fd4a1097fb6ebf6f5c -b 5.0
+git checkout aad0799955d93793e0b3659f29deaa19f74c25fe -b 5.1
 rm -rf .git
 rm -rf .git
 cd ..
 cd ..
 mv ffead-cpp ffead-cpp-src
 mv ffead-cpp ffead-cpp-src
@@ -50,4 +50,18 @@ then
 	rm -rf drogon
 	rm -rf drogon
 fi
 fi
 
 
+CURR_TYPE="nghttp2"
+if [ "$CURR_TYPE" = "nghttp2" ]
+then
+	apt install --no-install-recommends -y libjansson-dev libc-ares-dev libboost-all-dev
+	cd $IROOT
+	wget -q https://github.com/nghttp2/nghttp2/releases/download/v1.41.0/nghttp2-1.41.0.tar.gz
+	tar xvf nghttp2-1.41.0.tar.gz
+	cd nghttp2-1.41.0
+	cmake -DENABLE_ASIO_LIB=on -GNinja .
+	ninja install
+	cd $IROOT
+	rm -rf nghttp2-1.41.0
+fi
+
 rm -rf /var/lib/apt/lists/*
 rm -rf /var/lib/apt/lists/*

+ 4 - 0
frameworks/C++/ffead-cpp/install_ffead-cpp-dependencies.sh

@@ -7,6 +7,10 @@ apt update -yqq && apt install --no-install-recommends -yqq autoconf-archive unz
 #redis will not start correctly on bionic with this config
 #redis will not start correctly on bionic with this config
 sed -i "s/bind .*/bind 127.0.0.1/g" /etc/redis/redis.conf
 sed -i "s/bind .*/bind 127.0.0.1/g" /etc/redis/redis.conf
 
 
+echo never > /sys/kernel/mm/transparent_hugepage/enabled
+echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.local
+sysctl vm.overcommit_memory=1
+
 service apache2 stop
 service apache2 stop
 service memcached stop
 service memcached stop
 service redis-server stop
 service redis-server stop

+ 6 - 7
frameworks/C++/ffead-cpp/install_ffead-cpp-framework.sh

@@ -12,10 +12,12 @@ chmod 755 *.sh resources/*.sh rtdcf/autotools/*.sh
 rm -rf web/te-benchmark-um
 rm -rf web/te-benchmark-um
 rm -rf web/te-benchmark-um-pq
 rm -rf web/te-benchmark-um-pq
 rm -rf web/te-benchmark-um-mgr
 rm -rf web/te-benchmark-um-mgr
+rm -rf web/te-benchmark-um-pq-async
 mv ${IROOT}/server.sh script/
 mv ${IROOT}/server.sh script/
 mv ${IROOT}/te-benchmark-um web/
 mv ${IROOT}/te-benchmark-um web/
 mv ${IROOT}/te-benchmark-um-pq web/
 mv ${IROOT}/te-benchmark-um-pq web/
 mv ${IROOT}/te-benchmark-um-mgr web/
 mv ${IROOT}/te-benchmark-um-mgr web/
+mv ${IROOT}/te-benchmark-um-pq-async web/
 sed -i 's|THRD_PSIZ=6|THRD_PSIZ='${SERV_THREADS}'|g' resources/server.prop
 sed -i 's|THRD_PSIZ=6|THRD_PSIZ='${SERV_THREADS}'|g' resources/server.prop
 sed -i 's|W_THRD_PSIZ=2|W_THRD_PSIZ='${WRIT_THREADS}'|g' resources/server.prop
 sed -i 's|W_THRD_PSIZ=2|W_THRD_PSIZ='${WRIT_THREADS}'|g' resources/server.prop
 sed -i 's|ENABLE_CRS=true|ENABLE_CRS=false|g' resources/server.prop
 sed -i 's|ENABLE_CRS=true|ENABLE_CRS=false|g' resources/server.prop
@@ -42,6 +44,7 @@ sed -i 's|localhost|tfb-database|g' web/te-benchmark-um/config/sdormmysql.xml
 sed -i 's|localhost|tfb-database|g' web/te-benchmark-um/config/sdormpostgresql.xml
 sed -i 's|localhost|tfb-database|g' web/te-benchmark-um/config/sdormpostgresql.xml
 sed -i 's|localhost|tfb-database|g' web/te-benchmark-um-pq/config/sdorm.xml
 sed -i 's|localhost|tfb-database|g' web/te-benchmark-um-pq/config/sdorm.xml
 sed -i 's|localhost|tfb-database|g' web/te-benchmark-um-mgr/config/sdorm.xml
 sed -i 's|localhost|tfb-database|g' web/te-benchmark-um-mgr/config/sdorm.xml
+sed -i 's|localhost|tfb-database|g' web/te-benchmark-um-pq-async/config/sdorm.xml
 sed -i 's|127.0.0.1|tfb-database|g' resources/sample-odbcinst.ini
 sed -i 's|127.0.0.1|tfb-database|g' resources/sample-odbcinst.ini
 sed -i 's|127.0.0.1|tfb-database|g' resources/sample-odbc.ini
 sed -i 's|127.0.0.1|tfb-database|g' resources/sample-odbc.ini
 sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/default)||g' CMakeLists.txt
 sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/default)||g' CMakeLists.txt
@@ -63,7 +66,9 @@ sed -i 's|web/markers/src/autotools/Makefile||g' configure.ac
 sed -i 's|web/te-benchmark/src/autotools/Makefile||g' configure.ac
 sed -i 's|web/te-benchmark/src/autotools/Makefile||g' configure.ac
 sed -i 's|web/peer-server/src/autotools/Makefile||g' configure.ac
 sed -i 's|web/peer-server/src/autotools/Makefile||g' configure.ac
 
 
-cmake -DSRV_ALL=on -DCINATRA_INCLUDES=${IROOT}/cinatra/include -DMOD_APACHE=on -DMOD_NGINX=on -DMOD_MEMCACHED=on -DMOD_REDIS=on -DMOD_SDORM_MONGO=on .
+#./autogen.sh
+#./configure --enable-debug=no --enable-apachemod=yes --enable-nginxmod=yes --enable-mod_sdormmongo=yes --enable-mod_sdormsql=yes --enable-mod_rediscache=yes --enable-mod_memcached=yes CPPFLAGS="$CPPFLAGS -I${IROOT}/include/libmongoc-1.0 -I${IROOT}/include/libbson-1.0 -I${IROOT}/include/" LDFLAGS="$LDFLAGS -L${IROOT} -L${IROOT}/lib"
+cmake -DSRV_ALL=on -DCINATRA_INCLUDES=${IROOT}/cinatra/include -DMOD_APACHE=on -DMOD_NGINX=on -DMOD_MEMCACHED=on -DMOD_REDIS=on -DMOD_SDORM_MONGO=on  -DDEBUG=${DEBUG} .
 
 
 cp resources/sample-odbcinst.ini ${IROOT}/odbcinst.ini
 cp resources/sample-odbcinst.ini ${IROOT}/odbcinst.ini
 cp resources/sample-odbc.ini ${IROOT}/odbc.ini
 cp resources/sample-odbc.ini ${IROOT}/odbc.ini
@@ -81,9 +86,6 @@ rm -f /usr/local/lib/libdinter.so
 
 
 cd ffead-cpp-5.0-bin
 cd ffead-cpp-5.0-bin
 #cache related dockerfiles will add the cache.xml accordingly whenever needed
 #cache related dockerfiles will add the cache.xml accordingly whenever needed
-rm -f web/te-benchmark-um/config/cache.xml
-rm -f web/te-benchmark-um-pq/config/cache.xml
-rm -f web/te-benchmark-um-mgr/config/cache.xml
 chmod 755 *.sh resources/*.sh rtdcf/autotools/*.sh
 chmod 755 *.sh resources/*.sh rtdcf/autotools/*.sh
 ./server.sh &
 ./server.sh &
 while [ ! -f lib/libinter.so ]
 while [ ! -f lib/libinter.so ]
@@ -118,9 +120,6 @@ make install -j${MAX_THREADS}
 
 
 cd ffead-cpp-5.0-bin
 cd ffead-cpp-5.0-bin
 #cache related dockerfiles will add the cache.xml accordingly whenever needed
 #cache related dockerfiles will add the cache.xml accordingly whenever needed
-rm -f web/te-benchmark-um/config/cache.xml
-rm -f web/te-benchmark-um-pq/config/cache.xml
-rm -f web/te-benchmark-um-mgr/config/cache.xml
 chmod 755 *.sh resources/*.sh rtdcf/autotools/*.sh
 chmod 755 *.sh resources/*.sh rtdcf/autotools/*.sh
 ./server.sh &
 ./server.sh &
 while [ ! -f lib/libinter.so ]
 while [ ! -f lib/libinter.so ]

+ 65 - 117
frameworks/C++/ffead-cpp/run_ffead.sh

@@ -14,10 +14,6 @@ ln -s ${FFEAD_CPP_PATH}/lib/libinter.so /usr/local/lib/libinter.so
 ln -s ${FFEAD_CPP_PATH}/lib/libdinter.so /usr/local/lib/libdinter.so
 ln -s ${FFEAD_CPP_PATH}/lib/libdinter.so /usr/local/lib/libdinter.so
 ldconfig
 ldconfig
 
 
-echo never > /sys/kernel/mm/transparent_hugepage/enabled
-echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.local
-sysctl vm.overcommit_memory=1
-
 if [ "$2" = "nginx" ]
 if [ "$2" = "nginx" ]
 then
 then
 	if [ "$3" = "mysql" ] || [ "$3" = "postgresql" ]
 	if [ "$3" = "mysql" ] || [ "$3" = "postgresql" ]
@@ -44,58 +40,52 @@ service redis-server stop
 service apache2 stop
 service apache2 stop
 service memcached stop
 service memcached stop
 
 
-rm -f /tmp/cache.lock
-rm -f web/te-benchmark-um/config/cache.xml
-rm -f web/te-benchmark-um-pq/config/cache.xml
-rm -f web/te-benchmark-um-mgr/config/cache.xml
-
-if [ "$4" = "redis" ]
-then
-	service redis-server start
-	cp -f web/te-benchmark-um/config/cacheredis.xml web/te-benchmark-um/config/cache.xml
-	cp -f web/te-benchmark-um-pq/config/cacheredis.xml web/te-benchmark-um-pq/config/cache.xml
-	cp -f web/te-benchmark-um-mgr/config/cacheredis.xml web/te-benchmark-um-mgr/config/cache.xml
-fi
-
-if [ "$4" = "memcached" ]
-then
-	service memcached start
-	cp -f web/te-benchmark-um/config/cachememcached.xml web/te-benchmark-um/config/cache.xml
-	cp -f web/te-benchmark-um-pq/config/cachememcached.xml web/te-benchmark-um-pq/config/cache.xml
-	cp -f web/te-benchmark-um-mgr/config/cachememcached.xml web/te-benchmark-um-mgr/config/cache.xml
-fi
-
 if [ "$3" = "mongo" ]
 if [ "$3" = "mongo" ]
 then
 then
-	rm -f web/te-benchmark-um-pq/config/cache.xml
-	rm -f web/te-benchmark-um-mgr/config/cache.xml
-	cp -f web/te-benchmark-um/config/sdormmongo.xml web/te-benchmark-um/config/sdorm.xml
-fi
-
-if [ "$3" = "mongo-raw" ]
+	WEB_DIR=$FFEAD_CPP_PATH/web/te-benchmark-um
+	rm -rf web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async
+	cp -f ${WEB_DIR}/config/sdormmongo.xml ${WEB_DIR}/config/sdorm.xml
+elif [ "$3" = "mongo-raw" ]
 then
 then
-	rm -f web/te-benchmark-um-pq/config/cache.xml
-	rm -f web/te-benchmark-um/config/cache.xml
-fi
-
-if [ "$3" = "mysql" ]
+	WEB_DIR=$FFEAD_CPP_PATH/web/te-benchmark-um-mgr
+	rm -rf web/te-benchmark-um web/te-benchmark-um-pq web/te-benchmark-um-pq-async
+elif [ "$3" = "mysql" ]
 then
 then
-	rm -f web/te-benchmark-um-pq/config/cache.xml
-	rm -f web/te-benchmark-um-mgr/config/cache.xml
-	cp -f web/te-benchmark-um/config/sdormmysql.xml web/te-benchmark-um/config/sdorm.xml
-fi
-
-if [ "$3" = "postgresql" ]
+	WEB_DIR=$FFEAD_CPP_PATH/web/te-benchmark-um
+	rm -rf web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async
+	cp -f ${WEB_DIR}/config/sdormmysql.xml ${WEB_DIR}/config/sdorm.xml
+elif [ "$3" = "postgresql" ]
 then
 then
-	rm -f web/te-benchmark-um-pq/config/cache.xml
-	rm -f web/te-benchmark-um-mgr/config/cache.xml
+	WEB_DIR=$FFEAD_CPP_PATH/web/te-benchmark-um
+	rm -rf web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async
 	cp -f web/te-benchmark-um/config/sdormpostgresql.xml web/te-benchmark-um/config/sdorm.xml
 	cp -f web/te-benchmark-um/config/sdormpostgresql.xml web/te-benchmark-um/config/sdorm.xml
+elif [ "$3" = "postgresql-raw" ]
+then
+	WEB_DIR=$FFEAD_CPP_PATH/web/te-benchmark-um-pq
+	rm -rf web/te-benchmark-um web/te-benchmark-um-mgr web/te-benchmark-um-pq-async
+	sed -i 's|<async>true</async>|<async>false</async>|g' ${WEB_DIR}/config/sdorm.xml
+elif [ "$3" = "postgresql-raw-async" ]
+then
+	WEB_DIR=$FFEAD_CPP_PATH/web/te-benchmark-um-pq-async
+	rm -rf web/te-benchmark-um web/te-benchmark-um-mgr web/te-benchmark-um-pq
+	sed -i 's|<async>false</async>|<async>true</async>|g' ${WEB_DIR}/config/sdorm.xml
+else
+	WEB_DIR=$FFEAD_CPP_PATH/web/te-benchmark-um
+	rm -rf web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async
+	sed -i'' -e "s|<init>TeBkUmRouter.updateCache</init>||g" ${WEB_DIR}/config/cache.xml
 fi
 fi
 
 
-if [ "$3" = "postgresql-raw" ]
+if [ "$4" = "memory" ]
+then
+	cp -f ${WEB_DIR}/config/cachememory.xml ${WEB_DIR}/config/cache.xml
+elif [ "$4" = "redis" ]
+then
+	service redis-server start
+	cp -f ${WEB_DIR}/config/cacheredis.xml ${WEB_DIR}/config/cache.xml
+elif [ "$4" = "memcached" ]
 then
 then
-	rm -f web/te-benchmark-um/config/cache.xml
-	rm -f web/te-benchmark-um-mgr/config/cache.xml
+	service memcached start
+	cp -f ${WEB_DIR}/config/cachememcached.xml ${WEB_DIR}/config/cache.xml
 fi
 fi
 
 
 rm -f rtdcf/*.d rtdcf/*.o 
 rm -f rtdcf/*.d rtdcf/*.o 
@@ -111,135 +101,97 @@ chmod 700 rtdcf/*
 
 
 if [ "$2" = "emb" ]
 if [ "$2" = "emb" ]
 then
 then
-	sed -i 's|EVH_SINGLE=false|EVH_SINGLE=true|g' $FFEAD_CPP_PATH/resources/server.prop
+	sed -i 's|EVH_SINGLE=false|EVH_SINGLE=true|g' resources/server.prop
 	for i in $(seq 0 $(($(nproc --all)-1))); do
 	for i in $(seq 0 $(($(nproc --all)-1))); do
 		taskset -c $i ./ffead-cpp $FFEAD_CPP_PATH &
 		taskset -c $i ./ffead-cpp $FFEAD_CPP_PATH &
 	done
 	done
-fi
-
-if [ "$2" = "lithium" ]
+elif [ "$2" = "lithium" ]
 then
 then
 	./ffead-cpp-lithium $FFEAD_CPP_PATH &
 	./ffead-cpp-lithium $FFEAD_CPP_PATH &
-fi
-
-if [ "$2" = "cinatra" ]
+elif [ "$2" = "cinatra" ]
 then
 then
 	./ffead-cpp-cinatra $FFEAD_CPP_PATH &
 	./ffead-cpp-cinatra $FFEAD_CPP_PATH &
-fi
-
-if [ "$2" = "drogon" ]
+elif [ "$2" = "drogon" ]
 then
 then
 	./ffead-cpp-drogon $FFEAD_CPP_PATH &
 	./ffead-cpp-drogon $FFEAD_CPP_PATH &
-fi
-
-if [ "$2" = "apache" ]
+elif [ "$2" = "apache" ]
 then
 then
 	if [ "$3" = "mysql" ] || [ "$3" = "postgresql" ]
 	if [ "$3" = "mysql" ] || [ "$3" = "postgresql" ]
 	then
 	then
 		sed -i 's|/installs/ffead-cpp-5.0|'/installs/ffead-cpp-5.0-sql'|g' /etc/apache2/apache2.conf
 		sed -i 's|/installs/ffead-cpp-5.0|'/installs/ffead-cpp-5.0-sql'|g' /etc/apache2/apache2.conf
 		sed -i 's|/installs/ffead-cpp-5.0|'/installs/ffead-cpp-5.0-sql'|g' /etc/apache2/sites-enabled/000-default.conf /etc/apache2/sites-enabled/ffead-site.conf
 		sed -i 's|/installs/ffead-cpp-5.0|'/installs/ffead-cpp-5.0-sql'|g' /etc/apache2/sites-enabled/000-default.conf /etc/apache2/sites-enabled/ffead-site.conf
 	fi
 	fi
-	sed -i 's|<pool-size>30</pool-size>|<pool-size>3</pool-size>|g' $FFEAD_CPP_PATH/web/te-benchmark-um/config/sdorm.xml
-	sed -i 's|<pool-size>10</pool-size>|<pool-size>2</pool-size>|g' $FFEAD_CPP_PATH/web/te-benchmark-um/config/cache.xml
-	sed -i 's|<pool-size>30</pool-size>|<pool-size>3</pool-size>|g' $FFEAD_CPP_PATH/web/te-benchmark-um-pq/config/sdorm.xml
-	sed -i 's|<pool-size>10</pool-size>|<pool-size>2</pool-size>|g' $FFEAD_CPP_PATH/web/te-benchmark-um-pq/config/cache.xml
-	sed -i 's|<pool-size>30</pool-size>|<pool-size>3</pool-size>|g' $FFEAD_CPP_PATH/web/te-benchmark-um-mgr/config/sdorm.xml
-	sed -i 's|<pool-size>10</pool-size>|<pool-size>2</pool-size>|g' $FFEAD_CPP_PATH/web/te-benchmark-um-mgr/config/cache.xml
+	sed -i 's|<pool-size>30</pool-size>|<pool-size>3</pool-size>|g' web/te-benchmark-um/config/sdorm.xml
+	sed -i 's|<pool-size>10</pool-size>|<pool-size>2</pool-size>|g' web/te-benchmark-um/config/cache.xml
 	apachectl -D FOREGROUND
 	apachectl -D FOREGROUND
-fi
-
-if [ "$2" = "nginx" ]
+elif [ "$2" = "nginx" ]
 then
 then
 	mkdir -p ${IROOT}/nginxfc/logs
 	mkdir -p ${IROOT}/nginxfc/logs
-	sed -i 's|<pool-size>30</pool-size>|<pool-size>3</pool-size>|g' $FFEAD_CPP_PATH/web/te-benchmark-um/config/sdorm.xml
-	sed -i 's|<pool-size>10</pool-size>|<pool-size>2</pool-size>|g' $FFEAD_CPP_PATH/web/te-benchmark-um/config/cache.xml
-	sed -i 's|<pool-size>30</pool-size>|<pool-size>3</pool-size>|g' $FFEAD_CPP_PATH/web/te-benchmark-um-pq/config/sdorm.xml
-	sed -i 's|<pool-size>10</pool-size>|<pool-size>2</pool-size>|g' $FFEAD_CPP_PATH/web/te-benchmark-um-pq/config/cache.xml
-	sed -i 's|<pool-size>30</pool-size>|<pool-size>3</pool-size>|g' $FFEAD_CPP_PATH/web/te-benchmark-um-mgr/config/sdorm.xml
-	sed -i 's|<pool-size>10</pool-size>|<pool-size>2</pool-size>|g' $FFEAD_CPP_PATH/web/te-benchmark-um-mgr/config/cache.xml
+	sed -i 's|<pool-size>30</pool-size>|<pool-size>3</pool-size>|g' web/te-benchmark-um/config/sdorm.xml
+	sed -i 's|<pool-size>10</pool-size>|<pool-size>2</pool-size>|g' web/te-benchmark-um/config/cache.xml
 	if [ "$3" = "mysql" ] || [ "$3" = "postgresql" ]
 	if [ "$3" = "mysql" ] || [ "$3" = "postgresql" ]
 	then
 	then
 		nginx -g 'daemon off;' -c ${IROOT}/nginx-ffead-sql/conf/nginx.conf
 		nginx -g 'daemon off;' -c ${IROOT}/nginx-ffead-sql/conf/nginx.conf
 	else
 	else
 		nginx -g 'daemon off;' -c ${IROOT}/nginx-ffead-mongo/conf/nginx.conf
 		nginx -g 'daemon off;' -c ${IROOT}/nginx-ffead-mongo/conf/nginx.conf
 	fi
 	fi
-fi
-
-if [ "$2" = "libreactor" ]
+elif [ "$2" = "libreactor" ]
 then
 then
 	cd ${IROOT}
 	cd ${IROOT}
 	./libreactor-ffead-cpp $FFEAD_CPP_PATH 8080
 	./libreactor-ffead-cpp $FFEAD_CPP_PATH 8080
-fi
-
-if [ "$2" = "crystal-http" ]
+elif [ "$2" = "h2o" ]
+then
+	cd ${IROOT}
+	./h2o_app $FFEAD_CPP_PATH 0.0.0.0 8080
+elif [ "$2" = "crystal-http" ]
 then
 then
 	cd ${IROOT}
 	cd ${IROOT}
 	for i in $(seq 0 $(($(nproc --all)-1))); do
 	for i in $(seq 0 $(($(nproc --all)-1))); do
 		taskset -c $i ./crystal-ffead-cpp.out --ffead-cpp-dir=$FFEAD_CPP_PATH --to=8080 &
 		taskset -c $i ./crystal-ffead-cpp.out --ffead-cpp-dir=$FFEAD_CPP_PATH --to=8080 &
 	done
 	done
-fi
-
-if [ "$2" = "crystal-h2o" ]
+elif [ "$2" = "crystal-h2o" ]
 then
 then
 	cd ${IROOT}
 	cd ${IROOT}
 	for i in $(seq 0 $(($(nproc --all)-1))); do
 	for i in $(seq 0 $(($(nproc --all)-1))); do
 	  taskset -c $i ./h2o-evloop-ffead-cpp.out --ffead-cpp-dir=$FFEAD_CPP_PATH --to=8080 &
 	  taskset -c $i ./h2o-evloop-ffead-cpp.out --ffead-cpp-dir=$FFEAD_CPP_PATH --to=8080 &
 	done
 	done
-fi
-
-if [ "$2" = "rust-actix" ]
+elif [ "$2" = "rust-actix" ]
 then
 then
 	cd ${IROOT}
 	cd ${IROOT}
 	./actix-ffead-cpp $FFEAD_CPP_PATH 8080
 	./actix-ffead-cpp $FFEAD_CPP_PATH 8080
-fi
-
-if [ "$2" = "rust-hyper" ]
+elif [ "$2" = "rust-hyper" ]
 then
 then
 	cd ${IROOT}
 	cd ${IROOT}
 	./hyper-ffead-cpp $FFEAD_CPP_PATH 8080
 	./hyper-ffead-cpp $FFEAD_CPP_PATH 8080
-fi
-
-if [ "$2" = "rust-thruster" ]
+elif [ "$2" = "rust-thruster" ]
 then
 then
 	cd ${IROOT}
 	cd ${IROOT}
 	./thruster-ffead-cpp $FFEAD_CPP_PATH 8080
 	./thruster-ffead-cpp $FFEAD_CPP_PATH 8080
-fi
-
-if [ "$2" = "rust-rocket" ]
+elif [ "$2" = "rust-rocket" ]
 then
 then
 	cd ${IROOT}
 	cd ${IROOT}
 	./rocket-ffead-cpp $FFEAD_CPP_PATH 8080
 	./rocket-ffead-cpp $FFEAD_CPP_PATH 8080
-fi
-
-if [ "$2" = "go-fasthttp" ]
+elif [ "$2" = "go-fasthttp" ]
 then
 then
 	cd ${IROOT}
 	cd ${IROOT}
 	./fasthttp-ffead-cpp --server_directory=$FFEAD_CPP_PATH -addr=8080
 	./fasthttp-ffead-cpp --server_directory=$FFEAD_CPP_PATH -addr=8080
-fi
-
-if [ "$2" = "go-gnet" ]
+elif [ "$2" = "go-gnet" ]
 then
 then
 	cd ${IROOT}
 	cd ${IROOT}
 	./gnet-ffead-cpp --server_directory=$FFEAD_CPP_PATH --port=8080
 	./gnet-ffead-cpp --server_directory=$FFEAD_CPP_PATH --port=8080
-fi
-
-if [ "$2" = "v-vweb" ]
+elif [ "$2" = "v-vweb" ]
 then
 then
 	cd ${IROOT}
 	cd ${IROOT}
 	for i in $(seq 0 $(($(nproc --all)-1))); do
 	for i in $(seq 0 $(($(nproc --all)-1))); do
 		taskset -c $i ./vweb --server_dir=$FFEAD_CPP_PATH --server_port=8080 &
 		taskset -c $i ./vweb --server_dir=$FFEAD_CPP_PATH --server_port=8080 &
 	done
 	done
-fi
-
-if [ "$2" = "v-picov" ]
+elif [ "$2" = "v-picov" ]
 then
 then
 	cd ${IROOT}
 	cd ${IROOT}
 	for i in $(seq 0 $(($(nproc --all)-1))); do
 	for i in $(seq 0 $(($(nproc --all)-1))); do
 		taskset -c $i ./main --server_dir=$FFEAD_CPP_PATH --server_port=8080 &
 		taskset -c $i ./main --server_dir=$FFEAD_CPP_PATH --server_port=8080 &
 	done
 	done
-fi
-
-if [ "$2" = "java-firenio" ]
+elif [ "$2" = "java-firenio" ]
 then
 then
 	cd ${IROOT}
 	cd ${IROOT}
 	java                       \
 	java                       \
@@ -261,17 +213,13 @@ then
 	    -Dcachedurl=false          \
 	    -Dcachedurl=false          \
 	    -DunsafeBuf=true           \
 	    -DunsafeBuf=true           \
 	    -classpath firenio-ffead-cpp-0.1-jar-with-dependencies.jar com.firenio.ffeadcpp.FirenioFfeadCppServer $FFEAD_CPP_PATH 8080
 	    -classpath firenio-ffead-cpp-0.1-jar-with-dependencies.jar com.firenio.ffeadcpp.FirenioFfeadCppServer $FFEAD_CPP_PATH 8080
-fi
-
-if [ "$2" = "java-rapidoid" ]
+elif [ "$2" = "java-rapidoid" ]
 then
 then
 	cd ${IROOT}
 	cd ${IROOT}
 	java -server -XX:+UseNUMA -XX:+UseParallelGC -XX:+AggressiveOpts \
 	java -server -XX:+UseNUMA -XX:+UseParallelGC -XX:+AggressiveOpts \
 		-classpath rapidoid-ffead-cpp-1.0-jar-with-dependencies.jar \
 		-classpath rapidoid-ffead-cpp-1.0-jar-with-dependencies.jar \
 		com.rapidoid.ffeadcpp.Main $FFEAD_CPP_PATH 8080 profiles=production
 		com.rapidoid.ffeadcpp.Main $FFEAD_CPP_PATH 8080 profiles=production
-fi
-
-if [ "$2" = "java-wizzardo-http" ]
+elif [ "$2" = "java-wizzardo-http" ]
 then
 then
 	cd ${IROOT}
 	cd ${IROOT}
 	java -Xmx2G -Xms2G -server -XX:+UseNUMA -XX:+UseParallelGC -XX:+AggressiveOpts \
 	java -Xmx2G -Xms2G -server -XX:+UseNUMA -XX:+UseParallelGC -XX:+AggressiveOpts \

+ 7 - 0
frameworks/C++/ffead-cpp/te-benchmark-um-mgr/config/cachememory.xml

@@ -0,0 +1,7 @@
+<caches>
+        <cache>
+                <init>TeBkUmMgrRouter.updateCache</init>
+                <name>Memory-Cached</name>
+                <type>memory</type>
+        </cache>
+</caches>

+ 9 - 1
frameworks/C++/ffead-cpp/te-benchmark-um-mgr/include/TeBkUmMgr.h

@@ -82,6 +82,10 @@ class TeBkUmMgrRouter : public Router {
 	static const std::string HELLO_WORLD;
 	static const std::string HELLO_WORLD;
 	static std::string WORLD;
 	static std::string WORLD;
 	static std::string FORTUNE;
 	static std::string FORTUNE;
+
+	static std::string APP_NAME;
+	static std::string TPE_FN_NAME;
+
 	bool strToNum(const char* str, int len, int& ret);
 	bool strToNum(const char* str, int len, int& ret);
 
 
 	void db(TeBkUmMgrWorld&);
 	void db(TeBkUmMgrWorld&);
@@ -100,10 +104,14 @@ class TeBkUmMgrRouter : public Router {
 	void getContext(HttpRequest* request, Context* context);
 	void getContext(HttpRequest* request, Context* context);
 #ifdef INC_SDORM_MONGO
 #ifdef INC_SDORM_MONGO
 	static void getContextUtil(void* ctx, int rn, std::vector<MgRawRes>& data);
 	static void getContextUtil(void* ctx, int rn, std::vector<MgRawRes>& data);
+	MongoDBRawDataSourceImpl* sqli;
+	MongoDBRawDataSourceImpl* getDb();
 #endif
 #endif
 public:
 public:
+	TeBkUmMgrRouter();
+	virtual ~TeBkUmMgrRouter();
 	void updateCache();
 	void updateCache();
-	void route(HttpRequest* req, HttpResponse* res, void* dlib, void* ddlib);
+	bool route(HttpRequest* req, HttpResponse* res, void* dlib, void* ddlib, SocketInterface* sif);
 };
 };
 
 
 #endif /* WEB_TE_BENCHMARK_UM_INCLUDE_TeBkUmMgr_H_ */
 #endif /* WEB_TE_BENCHMARK_UM_INCLUDE_TeBkUmMgr_H_ */

+ 34 - 19
frameworks/C++/ffead-cpp/te-benchmark-um-mgr/src/TeBkUmMgr.cpp

@@ -89,7 +89,7 @@ std::string TeBkUmMgrRouter::FORTUNE = "fortune";
 
 
 void TeBkUmMgrRouter::db(TeBkUmMgrWorld& w) {
 void TeBkUmMgrRouter::db(TeBkUmMgrWorld& w) {
 #ifdef INC_SDORM_MONGO
 #ifdef INC_SDORM_MONGO
-	MongoDBRawDataSourceImpl* sqli = static_cast<MongoDBRawDataSourceImpl*>(DataSourceManager::getRawImpl());
+	MongoDBRawDataSourceImpl* sqli = getDb();
 	int rid = rand() % 10000 + 1;
 	int rid = rand() % 10000 + 1;
 	try {
 	try {
 		bson_t q = BSON_INITIALIZER;
 		bson_t q = BSON_INITIALIZER;
@@ -98,9 +98,7 @@ void TeBkUmMgrRouter::db(TeBkUmMgrWorld& w) {
 		sqli->executeQuery(&q, &w, &TeBkUmMgrRouter::dbUtil);
 		sqli->executeQuery(&q, &w, &TeBkUmMgrRouter::dbUtil);
 		sqli->end();
 		sqli->end();
 		bson_destroy(&q);
 		bson_destroy(&q);
-		DataSourceManager::cleanRawImpl(sqli);
 	} catch(const std::exception& e) {
 	} catch(const std::exception& e) {
-		DataSourceManager::cleanRawImpl(sqli);
 		throw e;
 		throw e;
 	}
 	}
 #endif
 #endif
@@ -131,7 +129,7 @@ void TeBkUmMgrRouter::queries(const char* q, int ql, std::vector<TeBkUmMgrWorld>
 	if(queryCount<1)queryCount=1;
 	if(queryCount<1)queryCount=1;
 	else if(queryCount>500)queryCount=500;
 	else if(queryCount>500)queryCount=500;
 #ifdef INC_SDORM_MONGO
 #ifdef INC_SDORM_MONGO
-	MongoDBRawDataSourceImpl* sqli = static_cast<MongoDBRawDataSourceImpl*>(DataSourceManager::getRawImpl());
+	MongoDBRawDataSourceImpl* sqli = getDb();
 
 
 	try {
 	try {
 		TeBkUmMgrWorld w;
 		TeBkUmMgrWorld w;
@@ -145,9 +143,7 @@ void TeBkUmMgrRouter::queries(const char* q, int ql, std::vector<TeBkUmMgrWorld>
 			wlst.push_back(w);
 			wlst.push_back(w);
 		}
 		}
 		sqli->end();
 		sqli->end();
-		DataSourceManager::cleanRawImpl(sqli);
 	} catch(const std::exception& e) {
 	} catch(const std::exception& e) {
-		DataSourceManager::cleanRawImpl(sqli);
 		throw e;
 		throw e;
 	}
 	}
 #endif
 #endif
@@ -159,7 +155,7 @@ void TeBkUmMgrRouter::updates(const char* q, int ql, std::vector<TeBkUmMgrWorld>
 	if(queryCount<1)queryCount=1;
 	if(queryCount<1)queryCount=1;
 	else if(queryCount>500)queryCount=500;
 	else if(queryCount>500)queryCount=500;
 #ifdef INC_SDORM_MONGO
 #ifdef INC_SDORM_MONGO
-	MongoDBRawDataSourceImpl* sqli = static_cast<MongoDBRawDataSourceImpl*>(DataSourceManager::getRawImpl());
+	MongoDBRawDataSourceImpl* sqli = getDb();
 
 
 	try {
 	try {
 		sqli->startBulk(WORLD);
 		sqli->startBulk(WORLD);
@@ -194,18 +190,16 @@ void TeBkUmMgrRouter::updates(const char* q, int ql, std::vector<TeBkUmMgrWorld>
 			wlst.push_back(w);
 			wlst.push_back(w);
 		}
 		}
 		sqli->endBulk();
 		sqli->endBulk();
-		DataSourceManager::cleanRawImpl(sqli);
 	} catch(const std::exception& e) {
 	} catch(const std::exception& e) {
-		DataSourceManager::cleanRawImpl(sqli);
 		throw e;
 		throw e;
 	}
 	}
 #endif
 #endif
 }
 }
 
 
 void TeBkUmMgrRouter::updateCache() {
 void TeBkUmMgrRouter::updateCache() {
-	CacheInterface* cchi = CacheManager::getImpl();
 #ifdef INC_SDORM_MONGO
 #ifdef INC_SDORM_MONGO
-	MongoDBRawDataSourceImpl* sqli = static_cast<MongoDBRawDataSourceImpl*>(DataSourceManager::getRawImpl());
+	CacheInterface* cchi = CacheManager::getImpl();
+	MongoDBRawDataSourceImpl* sqli = getDb();
 
 
 	try {
 	try {
 		std::vector<TeBkUmMgrWorld> wlist;
 		std::vector<TeBkUmMgrWorld> wlist;
@@ -219,10 +213,8 @@ void TeBkUmMgrRouter::updateCache() {
 			sprintf(str, "%d;%d", w.getId(), w.getRandomNumber());
 			sprintf(str, "%d;%d", w.getId(), w.getRandomNumber());
 			cchi->setRaw(CastUtil::fromNumber(w.getId()), str);
 			cchi->setRaw(CastUtil::fromNumber(w.getId()), str);
 		}
 		}
-		DataSourceManager::cleanRawImpl(sqli);
 		CacheManager::cleanImpl(cchi);
 		CacheManager::cleanImpl(cchi);
 	} catch(const std::exception& e) {
 	} catch(const std::exception& e) {
-		DataSourceManager::cleanRawImpl(sqli);
 		CacheManager::cleanImpl(cchi);
 		CacheManager::cleanImpl(cchi);
 		throw e;
 		throw e;
 	}
 	}
@@ -288,7 +280,7 @@ void TeBkUmMgrRouter::cachedWorlds(const char* q, int ql, std::vector<TeBkUmMgrW
 
 
 void TeBkUmMgrRouter::getContext(HttpRequest* request, Context* context) {
 void TeBkUmMgrRouter::getContext(HttpRequest* request, Context* context) {
 #ifdef INC_SDORM_MONGO
 #ifdef INC_SDORM_MONGO
-	MongoDBRawDataSourceImpl* sqli = static_cast<MongoDBRawDataSourceImpl*>(DataSourceManager::getRawImpl());
+	MongoDBRawDataSourceImpl* sqli = getDb();
 
 
 	try {
 	try {
 		std::vector<TeBkUmMgrFortune>* flst = new std::vector<TeBkUmMgrFortune>;
 		std::vector<TeBkUmMgrFortune>* flst = new std::vector<TeBkUmMgrFortune>;
@@ -303,9 +295,7 @@ void TeBkUmMgrRouter::getContext(HttpRequest* request, Context* context) {
 		std::sort (flst->begin(), flst->end());
 		std::sort (flst->begin(), flst->end());
 
 
 		context->insert(std::pair<std::string, void*>("fortunes", flst));
 		context->insert(std::pair<std::string, void*>("fortunes", flst));
-		DataSourceManager::cleanRawImpl(sqli);
 	} catch(...) {
 	} catch(...) {
-		DataSourceManager::cleanRawImpl(sqli);
 		throw;
 		throw;
 	}
 	}
 #endif
 #endif
@@ -342,7 +332,7 @@ bool TeBkUmMgrRouter::strToNum(const char* str, int len, int& ret) {
     return true;
     return true;
 }
 }
 
 
-void TeBkUmMgrRouter::route(HttpRequest* req, HttpResponse* res, void* dlib, void* ddlib) {
+bool TeBkUmMgrRouter::route(HttpRequest* req, HttpResponse* res, void* dlib, void* ddlib, SocketInterface* sif) {
 	//Timer t;
 	//Timer t;
 	//t.start();
 	//t.start();
 	std::string_view path = req->getPath();
 	std::string_view path = req->getPath();
@@ -400,8 +390,7 @@ void TeBkUmMgrRouter::route(HttpRequest* req, HttpResponse* res, void* dlib, voi
 		Context ctx;
 		Context ctx;
 		getContext(req, &ctx);
 		getContext(req, &ctx);
 
 
-		std::string fname = "_tebenchmarkummgrtpefortunestpeemittTemplateHTML";
-		void* mkr = dlsym(ddlib, fname.c_str());
+		void* mkr = dlsym(ddlib, TPE_FN_NAME.c_str());
 		if(mkr!=NULL)
 		if(mkr!=NULL)
 		{
 		{
 			TeBkUmMgrTemplatePtr f =  (TeBkUmMgrTemplatePtr)mkr;
 			TeBkUmMgrTemplatePtr f =  (TeBkUmMgrTemplatePtr)mkr;
@@ -447,4 +436,30 @@ void TeBkUmMgrRouter::route(HttpRequest* req, HttpResponse* res, void* dlib, voi
 		res->setHTTPResponseStatus(HTTPResponseStatus::NotFound);
 		res->setHTTPResponseStatus(HTTPResponseStatus::NotFound);
 	}
 	}
 	res->setDone(true);
 	res->setDone(true);
+	return true;
+}
+
+std::string TeBkUmMgrRouter::APP_NAME = "";
+std::string TeBkUmMgrRouter::TPE_FN_NAME = "";
+
+TeBkUmMgrRouter::TeBkUmMgrRouter() {
+#ifdef INC_SDORM_MONGO
+	sqli = NULL;
+#endif
+	if(APP_NAME=="") {
+		APP_NAME = CommonUtils::normalizeAppName("te-benchmark-um-mgr");
+		TPE_FN_NAME = CommonUtils::getTpeFnName("tpe/fortunes.tpe", "te-benchmark-um-mgr");
+	}
 }
 }
+
+TeBkUmMgrRouter::~TeBkUmMgrRouter() {
+}
+
+#ifdef INC_SDORM_MONGO
+MongoDBRawDataSourceImpl* TeBkUmMgrRouter::getDb() {
+	if(sqli==NULL) {
+		sqli = static_cast<MongoDBRawDataSourceImpl*>(DataSourceManager::getRawImpl("MongoDB-DSN", "te-benchmark-um-mgr"));
+	}
+	return sqli;
+}
+#endif

+ 10 - 0
frameworks/C++/ffead-cpp/te-benchmark-um-pq-async/CMakeLists.txt

@@ -0,0 +1,10 @@
+
+file(GLOB sources
+    "include/*.h"
+    "src/*.cpp"
+)
+
+include_directories("${CMAKE_SOURCE_DIR}/web/te-benchmark-um-pq-async/include")
+add_library(te_benchmark_um_pq_async SHARED ${sources})
+set_property(TARGET te_benchmark_um_pq_async PROPERTY POSITION_INDEPENDENT_CODE ON)
+target_link_libraries(te_benchmark_um_pq_async ffead-modules ffead-framework ${HAVE_PQLIB} ${HAVE_CURLLIB} ${HAVE_SSLLIB} ${HAVE_MEMCACHEDLIB} ${HAVE_ODBCLIB} ${HAVE_MONGOCLIB} ${HAVE_BSONLIB} ${HAVE_ZLIB} ${HAVE_CRYPTOLIB})

+ 24 - 0
frameworks/C++/ffead-cpp/te-benchmark-um-pq-async/config/application.xml

@@ -0,0 +1,24 @@
+<app libname="te_benchmark_um_pq_async" router="TeBkUmLpqAsyncRouter">
+	<cors-config>
+		<allow-origins>*</allow-origins>
+		<allow-methods>GET, POST, HEAD, PUT, DELETE</allow-methods>
+		<allow-headers>content-type, origin</allow-headers>
+		<expose-headers>content-type, origin</expose-headers>
+		<allow-credentials>true</allow-credentials>
+		<max-age>1023</max-age>
+	</cors-config>
+	<cache-control>
+		<control ext="png,css,js,jpeg,jpg,gif" header="Cache-Control"
+			value="max-age=290304000, public" />
+		<control ext="txt,xml,json" header="Cache-Control"
+			value="max-age=172800, public, must-revalidate" />
+		<control ext="html,html" header="Cache-Control"
+			value="max-age=7200, must-revalidate" />
+		<control file="video.mov" header="Expires"
+			value="Thu, 15 Apr 2020 20:00:00 GMT" />
+		<control header="Last-Modified" remove="true" />
+	</cache-control>
+	<templates>
+		<template class="TeBkUmLpqAsyncRouter" file="fortunes.tpe" path="fortunes"/>
+	</templates>
+</app>

+ 7 - 0
frameworks/C++/ffead-cpp/te-benchmark-um-pq-async/config/cachememory.xml

@@ -0,0 +1,7 @@
+<caches>
+        <cache>
+                <init>TeBkUmLpqAsyncRouter.updateCache</init>
+                <name>Memory-Cached</name>
+                <type>memory</type>
+        </cache>
+</caches>

+ 15 - 0
frameworks/C++/ffead-cpp/te-benchmark-um-pq-async/config/sdorm.xml

@@ -0,0 +1,15 @@
+<sdorm>
+	<data-source>
+		<config>
+			<nodes>
+				<node>
+					<url>host=localhost user=benchmarkdbuser password=benchmarkdbpass dbname=hello_world</url>
+				</node>
+			</nodes>
+			<pool-size>30</pool-size>
+			<name>PostgreSQL-DSN</name>
+			<type>sql-raw-pq</type>
+			<async>true</async>
+		</config>
+	</data-source>
+</sdorm>

+ 145 - 0
frameworks/C++/ffead-cpp/te-benchmark-um-pq-async/include/TeBkUmLpqAsync.h

@@ -0,0 +1,145 @@
+/*
+	Copyright 2009-2020, Sumeet Chhetri
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+*/
+/*
+ * TeBkUmLpqAsync.h
+ *
+ *  Created on: 03-Feb-2020
+ *      Author: sumeetc
+ */
+
+#ifndef WEB_TE_BENCHMARK_UM_INCLUDE_TeBkUmLpqAsync_H_
+#define WEB_TE_BENCHMARK_UM_INCLUDE_TeBkUmLpqAsync_H_
+#include "TemplateHandler.h"
+#include "vector"
+#ifndef OS_MINGW
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+#include "DataSourceManager.h"
+#include <stdlib.h>
+#include <algorithm>
+#include "CryptoHandler.h"
+#include "vector"
+#include "CastUtil.h"
+#include "CacheManager.h"
+#include <stdlib.h>
+#include "HttpRequest.h"
+#include "HttpResponse.h"
+#include "JSONSerialize.h"
+#include "string"
+#include "yuarel.h"
+#include "Router.h"
+
+typedef void (*TeBkUmLpqAsyncTemplatePtr) (Context*, std::string&);
+
+class TeBkUmLpqAsyncWorld {
+	int id;
+	int randomNumber;
+public:
+	TeBkUmLpqAsyncWorld();
+	virtual ~TeBkUmLpqAsyncWorld();
+	int getId() const;
+	void setId(int id);
+	int getRandomNumber() const;
+	void setRandomNumber(int randomNumber);
+};
+
+class TeBkUmLpqAsyncFortune {
+	int id;
+	std::string message;
+public:
+	TeBkUmLpqAsyncFortune();
+	virtual ~TeBkUmLpqAsyncFortune();
+	int getId() const;
+	void setId(int id);
+	const std::string& getMessage() const;
+	void setMessage(const std::string& message);
+	bool operator < (const TeBkUmLpqAsyncFortune& other) const;
+};
+
+class TeBkUmLpqAsyncMessage {
+	std::string message;
+public:
+	virtual ~TeBkUmLpqAsyncMessage();
+	const std::string& getMessage() const;
+	void setMessage(const std::string& message);
+};
+
+struct AsyncReq {
+	HttpResponse r;
+	SocketInterface* sif;
+	void* d;
+	void* ddlib;
+	LibpqDataSourceImpl* sqli;
+};
+
+struct CacheReq {
+	void* d;
+	CacheInterface* cchi;
+};
+
+class TeBkUmLpqAsyncRouter : public Router {
+	static const std::string HELLO_WORLD;
+	static std::string WORLD;
+	static std::string WORLD_ONE_QUERY;
+	static std::string WORLD_ALL_QUERY;
+	static std::string FORTUNE_ALL_QUERY;
+
+	static std::string APP_NAME;
+	static std::string TPE_FN_NAME;
+
+	std::atomic<bool> which = { false };
+
+	bool strToNum(const char* str, int len, int& ret);
+
+	void dbAsync(AsyncReq* req);
+	static void dbAsyncUtil(void* ctx, int rn, std::vector<LibpqRes>& data);
+	static void dbAsyncCh(void* ctx, bool status, std::string q, int counter);
+
+	void queriesAsync(const char* q, int ql, AsyncReq* req);
+	static void queriesAsyncUtil(void* ctx, int rn, std::vector<LibpqRes>& data);
+	static void queriesAsyncCh(void* ctx, bool status, std::string q, int counter);
+
+	void updatesAsync(const char* q, int ql, AsyncReq* req);
+	static void updatesAsyncChQ(void* ctx, bool status, std::string q, int counter);
+	static void updatesAsyncChU(void* ctx, bool status, std::string q, int counter);
+	
+	void cachedWorlds(const char*, int, std::vector<TeBkUmLpqAsyncWorld>&);
+	static void updateCacheAsyncUtil(void* ctx, int rn, std::vector<LibpqRes>& data);
+	static void updateCacheAsyncCh(void* ctx, bool status, std::string q, int counter);
+
+	void getContextAsync(AsyncReq* req);
+	static void getContextAsyncUtil(void* ctx, int rn, std::vector<LibpqRes>& data);
+	static void getContextAsyncCh(void* ctx, bool status, std::string q, int counter);
+
+	LibpqDataSourceImpl* sqli;
+	LibpqDataSourceImpl* getDb();
+public:
+	TeBkUmLpqAsyncRouter& operator=(const TeBkUmLpqAsyncRouter& a) {
+		which = false;
+		return *this;
+	}
+	TeBkUmLpqAsyncRouter(const TeBkUmLpqAsyncRouter& a) {
+		which = false;
+		sqli = NULL;
+	}
+	TeBkUmLpqAsyncRouter();
+	virtual ~TeBkUmLpqAsyncRouter();
+	void updateCache();
+	bool route(HttpRequest* req, HttpResponse* res, void* dlib, void* ddlib, SocketInterface* sif);
+};
+
+#endif /* WEB_TE_BENCHMARK_UM_INCLUDE_TeBkUmLpqAsync_H_ */

+ 503 - 0
frameworks/C++/ffead-cpp/te-benchmark-um-pq-async/src/TeBkUmLpqAsync.cpp

@@ -0,0 +1,503 @@
+/*
+	Copyright 2009-2020, Sumeet Chhetri
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+*/
+/*
+ * TeBkUmLpqAsyncUm.cpp
+ *
+ *  Created on: 03-Feb-2020
+ *      Author: sumeetc
+ */
+#include "TeBkUmLpqAsync.h"
+
+int TeBkUmLpqAsyncWorld::getId() const {
+	return id;
+}
+
+void TeBkUmLpqAsyncWorld::setId(int id) {
+	this->id = id;
+}
+
+int TeBkUmLpqAsyncWorld::getRandomNumber() const {
+	return randomNumber;
+}
+
+void TeBkUmLpqAsyncWorld::setRandomNumber(int randomNumber) {
+	this->randomNumber = randomNumber;
+}
+
+TeBkUmLpqAsyncWorld::TeBkUmLpqAsyncWorld() {
+	id = 0;
+	randomNumber = 0;
+}
+
+TeBkUmLpqAsyncWorld::~TeBkUmLpqAsyncWorld() {
+}
+
+int TeBkUmLpqAsyncFortune::getId() const {
+	return id;
+}
+
+void TeBkUmLpqAsyncFortune::setId(int id) {
+	this->id = id;
+}
+
+const std::string& TeBkUmLpqAsyncFortune::getMessage() const {
+	return message;
+}
+
+void TeBkUmLpqAsyncFortune::setMessage(const std::string& message) {
+	this->message = message;
+}
+
+TeBkUmLpqAsyncFortune::TeBkUmLpqAsyncFortune() {
+	id = 0;
+}
+
+TeBkUmLpqAsyncFortune::~TeBkUmLpqAsyncFortune() {
+}
+
+bool TeBkUmLpqAsyncFortune::operator < (const TeBkUmLpqAsyncFortune& other) const {
+	return message.compare(other.message)<0;
+}
+
+TeBkUmLpqAsyncMessage::~TeBkUmLpqAsyncMessage() {
+}
+
+const std::string& TeBkUmLpqAsyncMessage::getMessage() const {
+	return message;
+}
+
+void TeBkUmLpqAsyncMessage::setMessage(const std::string& message) {
+	this->message = message;
+}
+
+const std::string TeBkUmLpqAsyncRouter::HELLO_WORLD = "Hello, World!";
+std::string TeBkUmLpqAsyncRouter::WORLD = "world";
+std::string TeBkUmLpqAsyncRouter::WORLD_ONE_QUERY = "select id, randomnumber from world where id = $1";
+std::string TeBkUmLpqAsyncRouter::WORLD_ALL_QUERY = "select id, randomnumber from world";
+std::string TeBkUmLpqAsyncRouter::FORTUNE_ALL_QUERY = "select id, message from fortune";
+
+void TeBkUmLpqAsyncRouter::dbAsync(AsyncReq* req) {
+	req->d = new TeBkUmLpqAsyncWorld;
+	LibpqDataSourceImpl* sqli = getDb();
+	int rid = rand() % 10000 + 1;
+	try {
+		std::vector<LibpqParam> pars;
+		LibpqDataSourceImpl::ADD_INT4(pars, rid);
+		void* areq = sqli->executeQueryAsync(WORLD_ONE_QUERY, pars, req, &TeBkUmLpqAsyncRouter::dbAsyncUtil, &TeBkUmLpqAsyncRouter::dbAsyncCh, NULL);
+		sqli->completeAsync(areq);
+	} catch(const std::exception& e) {
+		throw e;
+	}
+}
+void TeBkUmLpqAsyncRouter::dbAsyncUtil(void* ctx, int rn, std::vector<LibpqRes>& data) {
+	AsyncReq* req = (AsyncReq*)ctx;
+	TeBkUmLpqAsyncWorld* w = (TeBkUmLpqAsyncWorld*)req->d;
+	w->setId(ntohl(*((uint32_t *) data.at(0).d)));
+	w->setRandomNumber(ntohl(*((uint32_t *) data.at(1).d)));
+}
+void TeBkUmLpqAsyncRouter::dbAsyncCh(void* ctx, bool status, std::string q, int counter) {
+	AsyncReq* req = (AsyncReq*)ctx;
+	TeBkUmLpqAsyncWorld* w = (TeBkUmLpqAsyncWorld*)req->d;
+	req->r.setContent(JSONSerialize::serializeUnknown(w, 0, "TeBkUmLpqAsyncWorld", APP_NAME));
+	req->r.setContentType(ContentTypes::CONTENT_TYPE_APPLICATION_JSON);
+	req->r.setHTTPResponseStatus(HTTPResponseStatus::Ok);
+	ResponseData d;
+	req->r.generateHeadResponse(d._b);
+	d._b += req->r.getContent();
+	req->sif->writeTo(&d);
+	req->sif->unUse();
+	delete w;
+	delete req;
+}
+
+
+void TeBkUmLpqAsyncRouter::queriesAsync(const char* q, int ql, AsyncReq* req) {
+	req->d = new std::vector<TeBkUmLpqAsyncWorld>;
+
+	int queryCount = 0;
+	strToNum(q, ql, queryCount);
+	if(queryCount<1)queryCount=1;
+	else if(queryCount>500)queryCount=500;
+
+	LibpqDataSourceImpl* sqli = getDb();
+
+	try {
+		void* areq = NULL;
+		for (int c = 0; c < queryCount; ++c) {
+			int rid = rand() % 10000 + 1;
+			std::vector<LibpqParam> pars;
+			LibpqDataSourceImpl::ADD_INT4(pars, rid);
+			areq = sqli->executeQueryAsync(WORLD_ONE_QUERY, pars, req, &TeBkUmLpqAsyncRouter::queriesAsyncUtil, &TeBkUmLpqAsyncRouter::queriesAsyncCh, areq);
+		}
+		sqli->completeAsync(areq);
+	} catch(const std::exception& e) {
+		throw e;
+	}
+}
+void TeBkUmLpqAsyncRouter::queriesAsyncUtil(void* ctx, int rn, std::vector<LibpqRes>& data) {
+	AsyncReq* req = (AsyncReq*)ctx;
+	std::vector<TeBkUmLpqAsyncWorld>* vec = (std::vector<TeBkUmLpqAsyncWorld>*)req->d;
+	TeBkUmLpqAsyncWorld w;
+	w.setId(ntohl(*((uint32_t *) data.at(0).d)));
+	w.setRandomNumber(ntohl(*((uint32_t *) data.at(1).d)));
+	vec->push_back(w);
+}
+void TeBkUmLpqAsyncRouter::queriesAsyncCh(void* ctx, bool status, std::string q, int counter) {
+	AsyncReq* req = (AsyncReq*)ctx;
+	std::vector<TeBkUmLpqAsyncWorld>* vec = (std::vector<TeBkUmLpqAsyncWorld>*)req->d;
+	req->r.setContent(JSONSerialize::serializeUnknown(vec, 100, "std::vector<TeBkUmLpqAsyncWorld>", APP_NAME));
+	req->r.setContentType(ContentTypes::CONTENT_TYPE_APPLICATION_JSON);
+	req->r.setHTTPResponseStatus(HTTPResponseStatus::Ok);
+	ResponseData d;
+	req->r.generateHeadResponse(d._b);
+	d._b += req->r.getContent();
+	req->sif->writeTo(&d);
+	req->sif->unUse();
+	delete vec;
+	delete req;
+}
+
+
+void TeBkUmLpqAsyncRouter::updatesAsync(const char* q, int ql, AsyncReq* req) {
+	req->d = new std::vector<TeBkUmLpqAsyncWorld>;
+
+	int queryCount = 0;
+	strToNum(q, ql, queryCount);
+	if(queryCount<1)queryCount=1;
+	else if(queryCount>500)queryCount=500;
+
+	LibpqDataSourceImpl* sqli = getDb();
+	req->sqli = sqli;
+
+	try {
+		void* areq = NULL;
+		for (int c = 0; c < queryCount; ++c) {
+			int rid = rand() % 10000 + 1;
+			std::vector<LibpqParam> pars;
+			LibpqDataSourceImpl::ADD_INT4(pars, rid);
+			areq = sqli->executeQueryAsync(WORLD_ONE_QUERY, pars, req, &TeBkUmLpqAsyncRouter::queriesAsyncUtil, &TeBkUmLpqAsyncRouter::updatesAsyncChQ, areq);
+		}
+		sqli->completeAsync(areq);
+	} catch(const std::exception& e) {
+		throw e;
+	}
+}
+void TeBkUmLpqAsyncRouter::updatesAsyncChQ(void* ctx, bool status, std::string q, int counter) {
+	AsyncReq* req = (AsyncReq*)ctx;
+	std::vector<TeBkUmLpqAsyncWorld>* vec = (std::vector<TeBkUmLpqAsyncWorld>*)req->d;
+
+	std::stringstream ss;
+	ss << "update world as t set randomnumber = c.randomnumber from (values";
+
+	std::vector<LibpqParam> pars;
+
+	int queryCount = (int)vec->size();
+	for (int c = 0; c < queryCount; ++c) {
+		int newRandomNumber = rand() % 10000 + 1;
+		if(vec->at(c).getRandomNumber() == newRandomNumber) {
+			newRandomNumber += 1;
+			if(newRandomNumber>=10000) {
+				newRandomNumber = 1;
+			}
+		}
+		vec->at(c).setRandomNumber(newRandomNumber);
+		ss << "(" << vec->at(c).getId() << "," << newRandomNumber << ")";
+		if(c!=queryCount-1) {
+			ss << ",";
+		}
+	}
+	ss << ") as c(id, randomnumber) where c.id = t.id";
+
+	LibpqDataSourceImpl* sqli = req->sqli;
+
+	AsyncReq* ar = new AsyncReq;
+	ar->sif = req->sif;
+	ar->r = std::move(req->r);
+	ar->d = req->d;
+	req->d = NULL;
+	req->sif = NULL;
+
+	try {
+		void* areq = sqli->beginAsync();
+		sqli->executeUpdateQueryAsync(ss.str(), pars, NULL, NULL, areq, false);
+		sqli->commitAsync(areq);
+		sqli->completeAsync(areq, ar, &TeBkUmLpqAsyncRouter::updatesAsyncChU);
+	} catch(const std::exception& e) {
+		throw e;
+	}
+}
+void TeBkUmLpqAsyncRouter::updatesAsyncChU(void* ctx, bool status, std::string q, int counter) {
+	AsyncReq* req = (AsyncReq*)ctx;
+	std::vector<TeBkUmLpqAsyncWorld>* vec = (std::vector<TeBkUmLpqAsyncWorld>*)req->d;
+	req->r.setContent(JSONSerialize::serializeUnknown(vec, 100, "std::vector<TeBkUmLpqAsyncWorld>", APP_NAME));
+	req->r.setContentType(ContentTypes::CONTENT_TYPE_APPLICATION_JSON);
+	req->r.setHTTPResponseStatus(HTTPResponseStatus::Ok);
+	ResponseData d;
+	req->r.generateHeadResponse(d._b);
+	d._b += req->r.getContent();
+	req->sif->writeTo(&d);
+	req->sif->unUse();
+	delete vec;
+	delete req;
+}
+
+void TeBkUmLpqAsyncRouter::updateCache() {
+	LibpqDataSourceImpl* sqli = getDb();
+
+	CacheReq* req = new CacheReq;
+	req->d = new std::vector<TeBkUmLpqAsyncWorld>;
+	req->cchi = CacheManager::getImpl();
+
+	try {
+		std::vector<LibpqParam> pars;
+		void* areq = sqli->executeQueryAsync(WORLD_ALL_QUERY, pars, req, &TeBkUmLpqAsyncRouter::updateCacheAsyncUtil, &TeBkUmLpqAsyncRouter::updateCacheAsyncCh, NULL);
+		sqli->completeAsync(areq);
+	} catch(const std::exception& e) {
+		throw e;
+	}
+}
+void TeBkUmLpqAsyncRouter::updateCacheAsyncUtil(void* ctx, int rn, std::vector<LibpqRes>& data) {
+	CacheReq* req = (CacheReq*)ctx;
+	std::vector<TeBkUmLpqAsyncWorld>* wlist = (std::vector<TeBkUmLpqAsyncWorld>*)req->d;
+	TeBkUmLpqAsyncWorld w;
+	w.setId(ntohl(*((uint32_t *) data.at(0).d)));
+	w.setRandomNumber(ntohl(*((uint32_t *) data.at(1).d)));
+	wlist->push_back(w);
+}
+void TeBkUmLpqAsyncRouter::updateCacheAsyncCh(void* ctx, bool status, std::string q, int counter) {
+	CacheReq* req = (CacheReq*)ctx;
+	std::vector<TeBkUmLpqAsyncWorld>* wlist = (std::vector<TeBkUmLpqAsyncWorld>*)req->d;
+	CacheInterface* cchi = req->cchi;
+
+	try {
+		for (int c = 0; c < (int)wlist->size(); ++c) {
+			TeBkUmLpqAsyncWorld& w = wlist->at(c);
+			char str[12];
+			sprintf(str, "%d;%d", w.getId(), w.getRandomNumber());
+			cchi->setRaw(CastUtil::fromNumber(w.getId()), str);
+		}
+		delete wlist;
+		CacheManager::cleanImpl(cchi);
+		delete req;
+	} catch(const std::exception& e) {
+		delete wlist;
+		CacheManager::cleanImpl(cchi);
+		delete req;
+		throw e;
+	}
+}
+
+void TeBkUmLpqAsyncRouter::cachedWorlds(const char* q, int ql, std::vector<TeBkUmLpqAsyncWorld>& wlst) {
+	int queryCount = 0;
+	strToNum(q, ql, queryCount);
+	if(queryCount<1)queryCount=1;
+	else if(queryCount>500)queryCount=500;
+
+	CacheInterface* cchi = CacheManager::getImpl();
+
+	try {
+		std::vector<std::string> keys;
+		for (int c = 0; c < queryCount; ++c) {
+			int rid = rand() % 10000 + 1;
+			TeBkUmLpqAsyncWorld w;
+			std::string v = cchi->getValue(CastUtil::fromNumber(rid));
+			size_t fn = v.find(";");
+			int tmp = 0;
+			strToNum(v.substr(0, fn).c_str(), fn, tmp);
+			w.setId(tmp);
+			tmp = 0;
+			strToNum(v.substr(fn+1).c_str(), v.length()-fn-1, tmp);
+			w.setRandomNumber(tmp);
+			wlst.push_back(w);
+		}
+		CacheManager::cleanImpl(cchi);
+	} catch(const std::exception& e) {
+		CacheManager::cleanImpl(cchi);
+		throw e;
+	}
+}
+
+
+void TeBkUmLpqAsyncRouter::getContextAsync(AsyncReq* req) {
+	req->d = new std::vector<TeBkUmLpqAsyncFortune>;
+
+	LibpqDataSourceImpl* sqli = getDb();
+
+	try {
+		std::vector<LibpqParam> pars;
+		void* areq = sqli->executeQueryAsync(FORTUNE_ALL_QUERY, pars, req, &TeBkUmLpqAsyncRouter::getContextAsyncUtil, &TeBkUmLpqAsyncRouter::getContextAsyncCh, NULL);
+		sqli->completeAsync(areq);
+	} catch(...) {
+		throw;
+	}
+}
+void TeBkUmLpqAsyncRouter::getContextAsyncUtil(void* ctx, int rn, std::vector<LibpqRes>& data) {
+	AsyncReq* req = (AsyncReq*)ctx;
+	std::vector<TeBkUmLpqAsyncFortune>* flst = (std::vector<TeBkUmLpqAsyncFortune>*)req->d;
+	TeBkUmLpqAsyncFortune w;
+	w.setId(ntohl(*((uint32_t *) data.at(0).d)));
+	std::string nm = std::string(data.at(1).d, data.at(1).l);
+	CryptoHandler::sanitizeHtml(nm);
+	w.setMessage(nm);
+	flst->push_back(w);
+}
+void TeBkUmLpqAsyncRouter::getContextAsyncCh(void* ctx, bool status, std::string q, int counter) {
+	AsyncReq* req = (AsyncReq*)ctx;
+	std::vector<TeBkUmLpqAsyncFortune>* flst = (std::vector<TeBkUmLpqAsyncFortune>*)req->d;
+
+	Context context;
+
+	TeBkUmLpqAsyncFortune nf;
+	nf.setId(0);
+	nf.setMessage("Additional fortune added at request time.");
+	flst->push_back(nf);
+	std::sort (flst->begin(), flst->end());
+
+	context.insert(std::pair<std::string, void*>("fortunes", flst));
+
+	void* mkr = dlsym(req->ddlib, TPE_FN_NAME.c_str());
+	if(mkr!=NULL)
+	{
+		TeBkUmLpqAsyncTemplatePtr f =  (TeBkUmLpqAsyncTemplatePtr)mkr;
+		std::string msg;
+		f(&context, msg);
+		req->r.setContent(msg);
+		req->r.setContentType(ContentTypes::CONTENT_TYPE_TEXT_SHTML);
+		req->r.setHTTPResponseStatus(HTTPResponseStatus::Ok);
+	}
+
+	ResponseData d;
+	req->r.generateHeadResponse(d._b);
+	d._b += req->r.getContent();
+	req->sif->writeTo(&d);
+	req->sif->unUse();
+}
+
+//https://stackoverflow.com/questions/9631225/convert-strings-specified-by-length-not-nul-terminated-to-int-float
+bool TeBkUmLpqAsyncRouter::strToNum(const char* str, int len, int& ret) {
+    ret = 0;
+    for(int i = 0; i < len; ++i)
+    {
+    	if(!isdigit(str[i])) return false;
+        ret = ret * 10 + (str[i] - '0');
+    }
+    return true;
+}
+
+bool TeBkUmLpqAsyncRouter::route(HttpRequest* req, HttpResponse* res, void* dlib, void* ddlib, SocketInterface* sif) {
+	std::string_view path = req->getPath();
+	if(StringUtil::endsWith(path, "/plaintext")) {
+		res->setContent(HELLO_WORLD);
+		res->setContentType(ContentTypes::CONTENT_TYPE_TEXT_PLAIN);
+		res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
+	} else if(StringUtil::endsWith(path, "/json")) {
+		TeBkUmLpqAsyncMessage msg;
+		msg.setMessage(HELLO_WORLD);
+		res->setContent(JSONSerialize::serializeUnknown(&msg, 0, "TeBkUmLpqAsyncMessage"));
+		res->setContentType(ContentTypes::CONTENT_TYPE_APPLICATION_JSON);
+		res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
+	} else if(StringUtil::endsWith(path, "/db")) {
+		AsyncReq* ar = new AsyncReq;
+		ar->sif = sif;
+		sif->use();
+		ar->r.addHeader(HttpResponse::DateHeader, res->getHeader(HttpResponse::DateHeader));
+		ar->r.update(req);
+		if(req->isClose()) {
+			ar->r.addHeader(HttpResponse::Connection, "close");
+		} else if(req->getHttpVers()>=1.1) {
+			ar->r.addHeader(HttpResponse::Connection, "keep-alive");
+		}
+		dbAsync(ar);
+		return false;
+	} else if(StringUtil::endsWith(path, "/queries")) {
+		struct yuarel_param params[1];
+		yuarel_parse_query((char*)req->getQueryStr().data(), req->getQueryStr().size(), params, 1);
+		AsyncReq* ar = new AsyncReq;
+		ar->sif = sif;
+		sif->use();
+		ar->r.addHeader(HttpResponse::DateHeader, res->getHeader(HttpResponse::DateHeader));
+		ar->r.update(req);
+		if(req->isClose()) {
+			ar->r.addHeader(HttpResponse::Connection, "close");
+		} else if(req->getHttpVers()>=1.1) {
+			ar->r.addHeader(HttpResponse::Connection, "keep-alive");
+		}
+		queriesAsync(params[0].val, params[0].val_len, ar);
+		return false;
+	} else if(StringUtil::endsWith(path, "/fortunes")) {
+		AsyncReq* ar = new AsyncReq;
+		ar->sif = sif;
+		sif->use();
+		ar->ddlib = ddlib;
+		ar->r.addHeader(HttpResponse::DateHeader, res->getHeader(HttpResponse::DateHeader));
+		ar->r.update(req);
+		if(req->isClose()) {
+			ar->r.addHeader(HttpResponse::Connection, "close");
+		} else if(req->getHttpVers()>=1.1) {
+			ar->r.addHeader(HttpResponse::Connection, "keep-alive");
+		}
+		getContextAsync(ar);
+		return false;
+	} else if(StringUtil::endsWith(path, "/updates")) {
+		struct yuarel_param params[1];
+		yuarel_parse_query((char*)req->getQueryStr().data(), req->getQueryStr().size(), params, 1);
+		AsyncReq* ar = new AsyncReq;
+		ar->sif = sif;
+		sif->use();
+		ar->r.addHeader(HttpResponse::DateHeader, res->getHeader(HttpResponse::DateHeader));
+		ar->r.update(req);
+		if(req->isClose()) {
+			ar->r.addHeader(HttpResponse::Connection, "close");
+		} else if(req->getHttpVers()>=1.1) {
+			ar->r.addHeader(HttpResponse::Connection, "keep-alive");
+		}
+		updatesAsync(params[0].val, params[0].val_len, ar);
+		return false;
+	} else if(StringUtil::endsWith(path, "/cached-worlds")) {
+		struct yuarel_param params[1];
+		yuarel_parse_query((char*)req->getQueryStr().data(), req->getQueryStr().size(), params, 1);
+		std::vector<TeBkUmLpqAsyncWorld> msg;
+		cachedWorlds(params[0].val, params[0].val_len, msg);
+		res->setContent(JSONSerialize::serializeUnknown(&msg, 100, "std::vector<TeBkUmLpqAsyncWorld>"));
+		res->setContentType(ContentTypes::CONTENT_TYPE_APPLICATION_JSON);
+		res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
+	} else {
+		res->setHTTPResponseStatus(HTTPResponseStatus::NotFound);
+	}
+	res->setDone(true);
+	return true;
+}
+
+std::string TeBkUmLpqAsyncRouter::APP_NAME = "";
+std::string TeBkUmLpqAsyncRouter::TPE_FN_NAME = "";
+
+TeBkUmLpqAsyncRouter::TeBkUmLpqAsyncRouter() {
+	sqli = NULL;
+	if(APP_NAME=="") {
+		APP_NAME = CommonUtils::normalizeAppName("te-benchmark-um-pq-async");
+		TPE_FN_NAME = CommonUtils::getTpeFnName("tpe/fortunes.tpe", "te-benchmark-um-pq-async");
+	}
+}
+
+TeBkUmLpqAsyncRouter::~TeBkUmLpqAsyncRouter() {
+}
+
+LibpqDataSourceImpl* TeBkUmLpqAsyncRouter::getDb() {
+	if(sqli==NULL) {
+		sqli = static_cast<LibpqDataSourceImpl*>(DataSourceManager::getRawImpl("PostgreSQL-DSN", "te-benchmark-um-pq-async"));
+	}
+	return sqli;
+}

+ 17 - 0
frameworks/C++/ffead-cpp/te-benchmark-um-pq-async/src/autotools/Makefile.am

@@ -0,0 +1,17 @@
+AUTOMAKE_OPTIONS = subdir-objects
+ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS}
+
+AM_CPPFLAGS=-I"../../../../include" -I"../../include"
+
+packageIdentifier=${PACKAGE_NAME}-${PACKAGE_VERSION}-bin
+distdir=${PACKAGE_NAME}-${PACKAGE_VERSION}-src
+fprefix=../../../../${packageIdentifier}
+prefix=${abs_builddir}
+
+lib_LTLIBRARIES = libte_benchmark_um_pq_async.la
+libte_benchmark_um_pq_async_la_SOURCES = ../TeBkUmLpqAsync.cpp
+
+libte_benchmark_um_pq_async_la_LDFLAGS = -no-undefined 
+libte_benchmark_um_pq_async_la_LIBADD = -L"${fprefix}/lib" -lffead-modules -lffead-framework
+
+#dist_noinst_SCRIPTS = autogen.sh

+ 13 - 0
frameworks/C++/ffead-cpp/te-benchmark-um-pq-async/tpe/fortunes.tpe

@@ -0,0 +1,13 @@
+#declare std::vector<TeBkUmLpqAsyncFortune> fortunes#
+<!DOCTYPE html>
+<html>
+<head><title>Fortunes</title></head>
+<body>
+<table>
+<tr><th>id</th><th>message</th></tr>
+#for(int i=0;i<(int)fortunes.size();i++)#
+<tr><td>$_S{fortunes.at(i).getId()}</td><td>${fortunes.at(i).getMessage()}</td></tr>
+#rof#
+</table>
+</body>
+</html>

+ 7 - 0
frameworks/C++/ffead-cpp/te-benchmark-um-pq/config/cachememory.xml

@@ -0,0 +1,7 @@
+<caches>
+        <cache>
+                <init>TeBkUmLpqRouter.updateCache</init>
+                <name>Memory-Cached</name>
+                <type>memory</type>
+        </cache>
+</caches>

+ 1 - 0
frameworks/C++/ffead-cpp/te-benchmark-um-pq/config/sdorm.xml

@@ -9,6 +9,7 @@
 			<pool-size>30</pool-size>
 			<pool-size>30</pool-size>
 			<name>PostgreSQL-DSN</name>
 			<name>PostgreSQL-DSN</name>
 			<type>sql-raw-pq</type>
 			<type>sql-raw-pq</type>
+			<async>false</async>
 		</config>
 		</config>
 	</data-source>
 	</data-source>
 </sdorm>
 </sdorm>

+ 23 - 2
frameworks/C++/ffead-cpp/te-benchmark-um-pq/include/TeBkUmLpq.h

@@ -57,6 +57,13 @@ public:
 	void setRandomNumber(int randomNumber);
 	void setRandomNumber(int randomNumber);
 };
 };
 
 
+struct UpdQrData {
+	std::vector<TeBkUmLpqWorld>* wlist;
+	std::stringstream* ss;
+	bool status;
+	int queryCount;
+};
+
 class TeBkUmLpqFortune {
 class TeBkUmLpqFortune {
 	int id;
 	int id;
 	std::string message;
 	std::string message;
@@ -84,23 +91,37 @@ class TeBkUmLpqRouter : public Router {
 	static std::string WORLD_ONE_QUERY;
 	static std::string WORLD_ONE_QUERY;
 	static std::string WORLD_ALL_QUERY;
 	static std::string WORLD_ALL_QUERY;
 	static std::string FORTUNE_ALL_QUERY;
 	static std::string FORTUNE_ALL_QUERY;
-	bool strToNum(const char* str, int len, int& ret);
+
+	static std::string APP_NAME;
+	static std::string TPE_FN_NAME;
+
+	static bool strToNum(const char* str, int len, int& ret);
 
 
 	void db(TeBkUmLpqWorld&);
 	void db(TeBkUmLpqWorld&);
 	void queries(const char*, int, std::vector<TeBkUmLpqWorld>&);
 	void queries(const char*, int, std::vector<TeBkUmLpqWorld>&);
+	void queriesMulti(const char*, int, std::vector<TeBkUmLpqWorld>&);
 	static void dbUtil(void* ctx, int rn, std::vector<LibpqRes>& data);
 	static void dbUtil(void* ctx, int rn, std::vector<LibpqRes>& data);
+	static void queriesMultiUtil(void* ctx, int rn, std::vector<LibpqRes>& data);
 
 
 	void updates(const char*, int, std::vector<TeBkUmLpqWorld>&);
 	void updates(const char*, int, std::vector<TeBkUmLpqWorld>&);
 	static void updatesUtil(void* ctx, int rn, std::vector<LibpqRes>& data);
 	static void updatesUtil(void* ctx, int rn, std::vector<LibpqRes>& data);
+	void updatesMulti(const char*, int, std::vector<TeBkUmLpqWorld>&);
+	static void updatesMultiUtil(void* ctx, int rn, std::vector<LibpqRes>& data);
+	static void updatesMultiUtilCh(void* ctx, bool status, std::string query, int counter);
 	
 	
 	void cachedWorlds(const char*, int, std::vector<TeBkUmLpqWorld>&);
 	void cachedWorlds(const char*, int, std::vector<TeBkUmLpqWorld>&);
 	static void updateCacheUtil(void* ctx, int rn, std::vector<LibpqRes>& data);
 	static void updateCacheUtil(void* ctx, int rn, std::vector<LibpqRes>& data);
 
 
 	void getContext(HttpRequest* request, Context* context);
 	void getContext(HttpRequest* request, Context* context);
 	static void getContextUtil(void* ctx, int rn, std::vector<LibpqRes>& data);
 	static void getContextUtil(void* ctx, int rn, std::vector<LibpqRes>& data);
+
+	LibpqDataSourceImpl* sqli;
+	LibpqDataSourceImpl* getDb();
 public:
 public:
+	TeBkUmLpqRouter();
+	virtual ~TeBkUmLpqRouter();
 	void updateCache();
 	void updateCache();
-	void route(HttpRequest* req, HttpResponse* res, void* dlib, void* ddlib);
+	bool route(HttpRequest* req, HttpResponse* res, void* dlib, void* ddlib, SocketInterface* sif);
 };
 };
 
 
 #endif /* WEB_TE_BENCHMARK_UM_INCLUDE_TeBkUmLpq_H_ */
 #endif /* WEB_TE_BENCHMARK_UM_INCLUDE_TeBkUmLpq_H_ */

+ 164 - 75
frameworks/C++/ffead-cpp/te-benchmark-um-pq/src/TeBkUmLpq.cpp

@@ -90,15 +90,13 @@ std::string TeBkUmLpqRouter::WORLD_ALL_QUERY = "select id, randomnumber from wor
 std::string TeBkUmLpqRouter::FORTUNE_ALL_QUERY = "select id, message from fortune";
 std::string TeBkUmLpqRouter::FORTUNE_ALL_QUERY = "select id, message from fortune";
 
 
 void TeBkUmLpqRouter::db(TeBkUmLpqWorld& w) {
 void TeBkUmLpqRouter::db(TeBkUmLpqWorld& w) {
-	LibpqDataSourceImpl* sqli = static_cast<LibpqDataSourceImpl*>(DataSourceManager::getRawImpl());
+	LibpqDataSourceImpl* sqli = getDb();
 	int rid = rand() % 10000 + 1;
 	int rid = rand() % 10000 + 1;
 	try {
 	try {
 		std::vector<LibpqParam> pars;
 		std::vector<LibpqParam> pars;
 		LibpqDataSourceImpl::ADD_INT4(pars, rid);
 		LibpqDataSourceImpl::ADD_INT4(pars, rid);
 		sqli->executeQuery(WORLD_ONE_QUERY, pars, &w, &TeBkUmLpqRouter::dbUtil);
 		sqli->executeQuery(WORLD_ONE_QUERY, pars, &w, &TeBkUmLpqRouter::dbUtil);
-		DataSourceManager::cleanRawImpl(sqli);
 	} catch(const std::exception& e) {
 	} catch(const std::exception& e) {
-		DataSourceManager::cleanRawImpl(sqli);
 		throw e;
 		throw e;
 	}
 	}
 }
 }
@@ -108,13 +106,14 @@ void TeBkUmLpqRouter::dbUtil(void* ctx, int rn, std::vector<LibpqRes>& data) {
 	w->setRandomNumber(ntohl(*((uint32_t *) data.at(1).d)));
 	w->setRandomNumber(ntohl(*((uint32_t *) data.at(1).d)));
 }
 }
 
 
+
 void TeBkUmLpqRouter::queries(const char* q, int ql, std::vector<TeBkUmLpqWorld>& wlst) {
 void TeBkUmLpqRouter::queries(const char* q, int ql, std::vector<TeBkUmLpqWorld>& wlst) {
 	int queryCount = 0;
 	int queryCount = 0;
 	strToNum(q, ql, queryCount);
 	strToNum(q, ql, queryCount);
 	if(queryCount<1)queryCount=1;
 	if(queryCount<1)queryCount=1;
 	else if(queryCount>500)queryCount=500;
 	else if(queryCount>500)queryCount=500;
 
 
-	LibpqDataSourceImpl* sqli = static_cast<LibpqDataSourceImpl*>(DataSourceManager::getRawImpl());
+	LibpqDataSourceImpl* sqli = getDb();
 
 
 	try {
 	try {
 		TeBkUmLpqWorld w;
 		TeBkUmLpqWorld w;
@@ -126,20 +125,59 @@ void TeBkUmLpqRouter::queries(const char* q, int ql, std::vector<TeBkUmLpqWorld>
 			sqli->executeQuery(WORLD_ONE_QUERY, pars, &w, &TeBkUmLpqRouter::dbUtil);
 			sqli->executeQuery(WORLD_ONE_QUERY, pars, &w, &TeBkUmLpqRouter::dbUtil);
 			wlst.push_back(w);
 			wlst.push_back(w);
 		}
 		}
-		DataSourceManager::cleanRawImpl(sqli);
 	} catch(const std::exception& e) {
 	} catch(const std::exception& e) {
-		DataSourceManager::cleanRawImpl(sqli);
 		throw e;
 		throw e;
 	}
 	}
 }
 }
 
 
+
+void TeBkUmLpqRouter::queriesMulti(const char* q, int ql, std::vector<TeBkUmLpqWorld>& wlst) {
+	int queryCount = 0;
+	strToNum(q, ql, queryCount);
+	if(queryCount<1)queryCount=1;
+	else if(queryCount>500)queryCount=500;
+
+	LibpqDataSourceImpl* sqli = getDb();
+
+	UpdQrData updt;
+	updt.wlist = &wlst;
+	updt.status = true;
+
+	try {
+		std::stringstream ss;
+		for (int c = 0; c < queryCount; ++c) {
+			int rid = rand() % 10000 + 1;
+			ss << "select id, randomnumber from world where id = " << rid << ";";
+		}
+		sqli->executeMultiQuery(ss.str(), &wlst, &TeBkUmLpqRouter::queriesMultiUtil, &TeBkUmLpqRouter::updatesMultiUtilCh);
+
+		if(!updt.status) {
+			wlst.clear();
+		}
+
+	} catch(const std::exception& e) {
+		throw e;
+	}
+}
+void TeBkUmLpqRouter::queriesMultiUtil(void* ctx, int rn, std::vector<LibpqRes>& data) {
+	std::vector<TeBkUmLpqWorld>* wlst = (std::vector<TeBkUmLpqWorld>*)ctx;
+	TeBkUmLpqWorld w;
+	int tmp = 0;
+	strToNum(data.at(0).d, data.at(0).l, tmp);
+	w.setId(tmp);
+	strToNum(data.at(1).d, data.at(1).l, tmp);
+	w.setRandomNumber(tmp);
+	wlst->push_back(w);
+}
+
+
 void TeBkUmLpqRouter::updates(const char* q, int ql, std::vector<TeBkUmLpqWorld>& wlst) {
 void TeBkUmLpqRouter::updates(const char* q, int ql, std::vector<TeBkUmLpqWorld>& wlst) {
 	int queryCount = 0;
 	int queryCount = 0;
 	strToNum(q, ql, queryCount);
 	strToNum(q, ql, queryCount);
 	if(queryCount<1)queryCount=1;
 	if(queryCount<1)queryCount=1;
 	else if(queryCount>500)queryCount=500;
 	else if(queryCount>500)queryCount=500;
 
 
-	LibpqDataSourceImpl* sqli = static_cast<LibpqDataSourceImpl*>(DataSourceManager::getRawImpl());
+	LibpqDataSourceImpl* sqli = getDb();
 
 
 	try {
 	try {
 		std::vector<LibpqParam> pars;
 		std::vector<LibpqParam> pars;
@@ -170,15 +208,13 @@ void TeBkUmLpqRouter::updates(const char* q, int ql, std::vector<TeBkUmLpqWorld>
 			LibpqDataSourceImpl::ADD_INT4(pars, w.getId());
 			LibpqDataSourceImpl::ADD_INT4(pars, w.getId());
 			LibpqDataSourceImpl::ADD_INT4(pars, w.getRandomNumber());
 			LibpqDataSourceImpl::ADD_INT4(pars, w.getRandomNumber());
 		}
 		}
-		ss << ") as c(randomnumber, id) where c.id = t.id";
+		ss << ") as c(id, randomnumber) where c.id = t.id";
 		
 		
 		sqli->begin();
 		sqli->begin();
 		sqli->executeUpdateQuery(ss.str(), pars);
 		sqli->executeUpdateQuery(ss.str(), pars);
 		sqli->commit();
 		sqli->commit();
-		DataSourceManager::cleanRawImpl(sqli);
 	} catch(const std::exception& e) {
 	} catch(const std::exception& e) {
 		sqli->rollback();
 		sqli->rollback();
-		DataSourceManager::cleanRawImpl(sqli);
 		throw e;
 		throw e;
 	}
 	}
 }
 }
@@ -191,14 +227,85 @@ void TeBkUmLpqRouter::updatesUtil(void* ctx, int rn, std::vector<LibpqRes>& data
 			newRandomNumber = 1;
 			newRandomNumber = 1;
 		}
 		}
 	}
 	}
-	LibpqDataSourceImpl::ADD_INT4(*pars, newRandomNumber);
 	uint32_t id = *(uint32_t *)data.at(0).d;
 	uint32_t id = *(uint32_t *)data.at(0).d;
 	LibpqDataSourceImpl::ADD_INT4(*pars, id, false);
 	LibpqDataSourceImpl::ADD_INT4(*pars, id, false);
+	LibpqDataSourceImpl::ADD_INT4(*pars, newRandomNumber);
 }
 }
 
 
+void TeBkUmLpqRouter::updatesMulti(const char* q, int ql, std::vector<TeBkUmLpqWorld>& wlst) {
+	int queryCount = 0;
+	strToNum(q, ql, queryCount);
+	if(queryCount<1)queryCount=1;
+	else if(queryCount>500)queryCount=500;
+
+	LibpqDataSourceImpl* sqli = getDb();
+
+	try {
+		std::stringstream ss, ssq;
+		ss << "begin;update world as t set randomnumber = c.randomnumber from (values";
+
+		UpdQrData updt;
+		updt.wlist = &wlst;
+		updt.ss = &ss;
+		updt.status = true;
+		updt.queryCount = queryCount;
+
+		for (int c = 0; c < queryCount; ++c) {
+			int rid = rand() % 10000 + 1;
+			ssq << "select id, randomnumber from world where id = " << rid << ";";
+		}
+
+		sqli->executeMultiQuery(ssq.str(), &updt, &TeBkUmLpqRouter::updatesMultiUtil, &TeBkUmLpqRouter::updatesMultiUtilCh);
+		ss << ") as c(id, randomnumber) where c.id = t.id;commit";
+
+		if(!updt.status) {
+			return;
+		}
+
+		sqli->executeUpdateMultiQuery(ss.str(), &updt, &TeBkUmLpqRouter::updatesMultiUtilCh);
+
+		if(!updt.status) {
+			wlst.clear();
+		}
+	} catch(const std::exception& e) {
+		sqli->rollback();
+		throw e;
+	}
+}
+void TeBkUmLpqRouter::updatesMultiUtil(void* ctx, int rn, std::vector<LibpqRes>& data) {
+	UpdQrData* updt = (UpdQrData*)ctx;
+	std::stringstream* ss = updt->ss;
+	TeBkUmLpqWorld w;
+	int tmp = 0;
+	strToNum(data.at(0).d, data.at(0).l, tmp);
+	w.setId(tmp);
+	strToNum(data.at(1).d, data.at(1).l, tmp);
+	int newRandomNumber = rand() % 10000 + 1;
+	if(tmp == newRandomNumber) {
+		newRandomNumber += 1;
+		if(newRandomNumber>=10000) {
+			newRandomNumber = 1;
+		}
+	}
+	w.setRandomNumber(newRandomNumber);
+	updt->wlist->push_back(w);
+	*ss << "(" << w.getId() << "," << w.getRandomNumber() << ")";
+	updt->queryCount--;
+	if(updt->queryCount>0) {
+		*ss << ",";
+	}
+}
+void TeBkUmLpqRouter::updatesMultiUtilCh(void* ctx, bool status, std::string query, int counter) {
+	UpdQrData* updt = (UpdQrData*)ctx;
+	if(!status) {
+		updt->status = status;
+	}
+}
+
+
 void TeBkUmLpqRouter::updateCache() {
 void TeBkUmLpqRouter::updateCache() {
 	CacheInterface* cchi = CacheManager::getImpl();
 	CacheInterface* cchi = CacheManager::getImpl();
-	LibpqDataSourceImpl* sqli = static_cast<LibpqDataSourceImpl*>(DataSourceManager::getRawImpl());
+	LibpqDataSourceImpl* sqli = getDb();
 
 
 	try {
 	try {
 		std::vector<TeBkUmLpqWorld> wlist;
 		std::vector<TeBkUmLpqWorld> wlist;
@@ -211,10 +318,8 @@ void TeBkUmLpqRouter::updateCache() {
 			sprintf(str, "%d;%d", w.getId(), w.getRandomNumber());
 			sprintf(str, "%d;%d", w.getId(), w.getRandomNumber());
 			cchi->setRaw(CastUtil::fromNumber(w.getId()), str);
 			cchi->setRaw(CastUtil::fromNumber(w.getId()), str);
 		}
 		}
-		DataSourceManager::cleanRawImpl(sqli);
 		CacheManager::cleanImpl(cchi);
 		CacheManager::cleanImpl(cchi);
 	} catch(const std::exception& e) {
 	} catch(const std::exception& e) {
-		DataSourceManager::cleanRawImpl(sqli);
 		CacheManager::cleanImpl(cchi);
 		CacheManager::cleanImpl(cchi);
 		throw e;
 		throw e;
 	}
 	}
@@ -239,15 +344,8 @@ void TeBkUmLpqRouter::cachedWorlds(const char* q, int ql, std::vector<TeBkUmLpqW
 		std::vector<std::string> keys;
 		std::vector<std::string> keys;
 		for (int c = 0; c < queryCount; ++c) {
 		for (int c = 0; c < queryCount; ++c) {
 			int rid = rand() % 10000 + 1;
 			int rid = rand() % 10000 + 1;
-			keys.push_back(CastUtil::fromNumber(rid));
-		}
-
-		std::vector<std::string> values;
-		cchi->mgetRaw(keys, values);
-
-		for (int c = 0; c < (int)values.size(); ++c) {
 			TeBkUmLpqWorld w;
 			TeBkUmLpqWorld w;
-			std::string& v = values.at(c);
+			std::string v = cchi->getValue(CastUtil::fromNumber(rid));
 			size_t fn = v.find(";");
 			size_t fn = v.find(";");
 			int tmp = 0;
 			int tmp = 0;
 			strToNum(v.substr(0, fn).c_str(), fn, tmp);
 			strToNum(v.substr(0, fn).c_str(), fn, tmp);
@@ -257,7 +355,6 @@ void TeBkUmLpqRouter::cachedWorlds(const char* q, int ql, std::vector<TeBkUmLpqW
 			w.setRandomNumber(tmp);
 			w.setRandomNumber(tmp);
 			wlst.push_back(w);
 			wlst.push_back(w);
 		}
 		}
-
 		CacheManager::cleanImpl(cchi);
 		CacheManager::cleanImpl(cchi);
 	} catch(const std::exception& e) {
 	} catch(const std::exception& e) {
 		CacheManager::cleanImpl(cchi);
 		CacheManager::cleanImpl(cchi);
@@ -266,7 +363,7 @@ void TeBkUmLpqRouter::cachedWorlds(const char* q, int ql, std::vector<TeBkUmLpqW
 }
 }
 
 
 void TeBkUmLpqRouter::getContext(HttpRequest* request, Context* context) {
 void TeBkUmLpqRouter::getContext(HttpRequest* request, Context* context) {
-	LibpqDataSourceImpl* sqli = static_cast<LibpqDataSourceImpl*>(DataSourceManager::getRawImpl());
+	LibpqDataSourceImpl* sqli = getDb();
 
 
 	try {
 	try {
 		std::vector<TeBkUmLpqFortune>* flst = new std::vector<TeBkUmLpqFortune>;
 		std::vector<TeBkUmLpqFortune>* flst = new std::vector<TeBkUmLpqFortune>;
@@ -280,9 +377,7 @@ void TeBkUmLpqRouter::getContext(HttpRequest* request, Context* context) {
 		std::sort (flst->begin(), flst->end());
 		std::sort (flst->begin(), flst->end());
 
 
 		context->insert(std::pair<std::string, void*>("fortunes", flst));
 		context->insert(std::pair<std::string, void*>("fortunes", flst));
-		DataSourceManager::cleanRawImpl(sqli);
 	} catch(...) {
 	} catch(...) {
-		DataSourceManager::cleanRawImpl(sqli);
 		throw;
 		throw;
 	}
 	}
 }
 }
@@ -296,6 +391,7 @@ void TeBkUmLpqRouter::getContextUtil(void* ctx, int rn, std::vector<LibpqRes>& d
 	flst->push_back(w);
 	flst->push_back(w);
 }
 }
 
 
+
 //https://stackoverflow.com/questions/9631225/convert-strings-specified-by-length-not-nul-terminated-to-int-float
 //https://stackoverflow.com/questions/9631225/convert-strings-specified-by-length-not-nul-terminated-to-int-float
 bool TeBkUmLpqRouter::strToNum(const char* str, int len, int& ret) {
 bool TeBkUmLpqRouter::strToNum(const char* str, int len, int& ret) {
     ret = 0;
     ret = 0;
@@ -307,66 +403,45 @@ bool TeBkUmLpqRouter::strToNum(const char* str, int len, int& ret) {
     return true;
     return true;
 }
 }
 
 
-void TeBkUmLpqRouter::route(HttpRequest* req, HttpResponse* res, void* dlib, void* ddlib) {
-	//Timer t;
-	//t.start();
+bool TeBkUmLpqRouter::route(HttpRequest* req, HttpResponse* res, void* dlib, void* ddlib, SocketInterface* sif) {
 	std::string_view path = req->getPath();
 	std::string_view path = req->getPath();
 	if(StringUtil::endsWith(path, "/plaintext")) {
 	if(StringUtil::endsWith(path, "/plaintext")) {
-		//t.end();
-		//CommonUtils::tsContRstLkp += t.timerNanoSeconds();
-		//t.start();
 		res->setContent(HELLO_WORLD);
 		res->setContent(HELLO_WORLD);
 		res->setContentType(ContentTypes::CONTENT_TYPE_TEXT_PLAIN);
 		res->setContentType(ContentTypes::CONTENT_TYPE_TEXT_PLAIN);
 		res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
 		res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
-		//t.end();
-		//CommonUtils::tsContRstSer += t.timerNanoSeconds();
 	} else if(StringUtil::endsWith(path, "/json")) {
 	} else if(StringUtil::endsWith(path, "/json")) {
-		//t.end();
-		//CommonUtils::tsContRstLkp += t.timerNanoSeconds();
-		//t.start();
 		TeBkUmLpqMessage msg;
 		TeBkUmLpqMessage msg;
 		msg.setMessage(HELLO_WORLD);
 		msg.setMessage(HELLO_WORLD);
 		res->setContent(JSONSerialize::serializeUnknown(&msg, 0, "TeBkUmLpqMessage"));
 		res->setContent(JSONSerialize::serializeUnknown(&msg, 0, "TeBkUmLpqMessage"));
 		res->setContentType(ContentTypes::CONTENT_TYPE_APPLICATION_JSON);
 		res->setContentType(ContentTypes::CONTENT_TYPE_APPLICATION_JSON);
 		res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
 		res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
-		//t.end();
-		//CommonUtils::tsContRstSer += t.timerNanoSeconds();
 	} else if(StringUtil::endsWith(path, "/db")) {
 	} else if(StringUtil::endsWith(path, "/db")) {
-		//t.end();
-		//CommonUtils::tsContRstLkp += t.timerNanoSeconds();
-		//t.start();
 		TeBkUmLpqWorld msg;
 		TeBkUmLpqWorld msg;
 		db(msg);
 		db(msg);
-		//t.end();
-		//CommonUtils::tsContExec += t.timerNanoSeconds();
-		//t.start();
 		res->setContent(JSONSerialize::serializeUnknown(&msg, 0, "TeBkUmLpqWorld"));
 		res->setContent(JSONSerialize::serializeUnknown(&msg, 0, "TeBkUmLpqWorld"));
 		res->setContentType(ContentTypes::CONTENT_TYPE_APPLICATION_JSON);
 		res->setContentType(ContentTypes::CONTENT_TYPE_APPLICATION_JSON);
 		res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
 		res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
-		//t.end();
-		//CommonUtils::tsContRstSer += t.timerNanoSeconds();
-	} else if(StringUtil::endsWith(path, "/queries")) {
-		//t.end();
-		//CommonUtils::tsContRstLkp += t.timerNanoSeconds();
-		//t.start();
+	} else if(StringUtil::endsWith(path, "/queries_old")) {
 		struct yuarel_param params[1];
 		struct yuarel_param params[1];
 		yuarel_parse_query((char*)req->getQueryStr().data(), req->getQueryStr().size(), params, 1);
 		yuarel_parse_query((char*)req->getQueryStr().data(), req->getQueryStr().size(), params, 1);
 		std::vector<TeBkUmLpqWorld> msg;
 		std::vector<TeBkUmLpqWorld> msg;
 		queries(params[0].val, params[0].val_len, msg);
 		queries(params[0].val, params[0].val_len, msg);
-		//t.end();
-		//CommonUtils::tsContExec += t.timerNanoSeconds();
-		//t.start();
 		res->setContent(JSONSerialize::serializeUnknown(&msg, 100, "std::vector<TeBkUmLpqWorld>"));
 		res->setContent(JSONSerialize::serializeUnknown(&msg, 100, "std::vector<TeBkUmLpqWorld>"));
 		res->setContentType(ContentTypes::CONTENT_TYPE_APPLICATION_JSON);
 		res->setContentType(ContentTypes::CONTENT_TYPE_APPLICATION_JSON);
 		res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
 		res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
-		//t.end();
-		//CommonUtils::tsContRstSer += t.timerNanoSeconds();
+	} else if(StringUtil::endsWith(path, "/queries")) {
+		struct yuarel_param params[1];
+		yuarel_parse_query((char*)req->getQueryStr().data(), req->getQueryStr().size(), params, 1);
+		std::vector<TeBkUmLpqWorld> msg;
+		queriesMulti(params[0].val, params[0].val_len, msg);
+		res->setContent(JSONSerialize::serializeUnknown(&msg, 100, "std::vector<TeBkUmLpqWorld>"));
+		res->setContentType(ContentTypes::CONTENT_TYPE_APPLICATION_JSON);
+		res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
 	} else if(StringUtil::endsWith(path, "/fortunes")) {
 	} else if(StringUtil::endsWith(path, "/fortunes")) {
 		Context ctx;
 		Context ctx;
 		getContext(req, &ctx);
 		getContext(req, &ctx);
 
 
-		std::string fname = "_tebenchmarkumpqtpefortunestpeemittTemplateHTML";
-		void* mkr = dlsym(ddlib, fname.c_str());
+		void* mkr = dlsym(ddlib, TPE_FN_NAME.c_str());
 		if(mkr!=NULL)
 		if(mkr!=NULL)
 		{
 		{
 			TeBkUmLpqTemplatePtr f =  (TeBkUmLpqTemplatePtr)mkr;
 			TeBkUmLpqTemplatePtr f =  (TeBkUmLpqTemplatePtr)mkr;
@@ -376,40 +451,54 @@ void TeBkUmLpqRouter::route(HttpRequest* req, HttpResponse* res, void* dlib, voi
 			res->setContentType(ContentTypes::CONTENT_TYPE_TEXT_SHTML);
 			res->setContentType(ContentTypes::CONTENT_TYPE_TEXT_SHTML);
 			res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
 			res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
 		}
 		}
-	} else if(StringUtil::endsWith(path, "/updates")) {
-		//t.end();
-		//CommonUtils::tsContRstLkp += t.timerNanoSeconds();
-		//t.start();
+	} else if(StringUtil::endsWith(path, "/updates_old")) {
 		struct yuarel_param params[1];
 		struct yuarel_param params[1];
 		yuarel_parse_query((char*)req->getQueryStr().data(), req->getQueryStr().size(), params, 1);
 		yuarel_parse_query((char*)req->getQueryStr().data(), req->getQueryStr().size(), params, 1);
 		std::vector<TeBkUmLpqWorld> msg;
 		std::vector<TeBkUmLpqWorld> msg;
 		updates(params[0].val, params[0].val_len, msg);
 		updates(params[0].val, params[0].val_len, msg);
-		//t.end();
-		//CommonUtils::tsContExec += t.timerNanoSeconds();
-		//t.start();
 		res->setContent(JSONSerialize::serializeUnknown(&msg, 100, "std::vector<TeBkUmLpqWorld>"));
 		res->setContent(JSONSerialize::serializeUnknown(&msg, 100, "std::vector<TeBkUmLpqWorld>"));
 		res->setContentType(ContentTypes::CONTENT_TYPE_APPLICATION_JSON);
 		res->setContentType(ContentTypes::CONTENT_TYPE_APPLICATION_JSON);
 		res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
 		res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
-		//t.end();
-		//CommonUtils::tsContRstSer += t.timerNanoSeconds();
+	} else if(StringUtil::endsWith(path, "/updates")) {
+		struct yuarel_param params[1];
+		yuarel_parse_query((char*)req->getQueryStr().data(), req->getQueryStr().size(), params, 1);
+		std::vector<TeBkUmLpqWorld> msg;
+		updatesMulti(params[0].val, params[0].val_len, msg);
+		res->setContent(JSONSerialize::serializeUnknown(&msg, 100, "std::vector<TeBkUmLpqWorld>"));
+		res->setContentType(ContentTypes::CONTENT_TYPE_APPLICATION_JSON);
+		res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
 	} else if(StringUtil::endsWith(path, "/cached-worlds")) {
 	} else if(StringUtil::endsWith(path, "/cached-worlds")) {
-		//t.end();
-		//CommonUtils::tsContRstLkp += t.timerNanoSeconds();
-		//t.start();
 		struct yuarel_param params[1];
 		struct yuarel_param params[1];
 		yuarel_parse_query((char*)req->getQueryStr().data(), req->getQueryStr().size(), params, 1);
 		yuarel_parse_query((char*)req->getQueryStr().data(), req->getQueryStr().size(), params, 1);
 		std::vector<TeBkUmLpqWorld> msg;
 		std::vector<TeBkUmLpqWorld> msg;
 		cachedWorlds(params[0].val, params[0].val_len, msg);
 		cachedWorlds(params[0].val, params[0].val_len, msg);
-		//t.end();
-		//CommonUtils::tsContExec += t.timerNanoSeconds();
-		//t.start();
 		res->setContent(JSONSerialize::serializeUnknown(&msg, 100, "std::vector<TeBkUmLpqWorld>"));
 		res->setContent(JSONSerialize::serializeUnknown(&msg, 100, "std::vector<TeBkUmLpqWorld>"));
 		res->setContentType(ContentTypes::CONTENT_TYPE_APPLICATION_JSON);
 		res->setContentType(ContentTypes::CONTENT_TYPE_APPLICATION_JSON);
 		res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
 		res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
-		//t.end();
-		//CommonUtils::tsContRstSer += t.timerNanoSeconds();
 	} else {
 	} else {
 		res->setHTTPResponseStatus(HTTPResponseStatus::NotFound);
 		res->setHTTPResponseStatus(HTTPResponseStatus::NotFound);
 	}
 	}
 	res->setDone(true);
 	res->setDone(true);
+	return true;
+}
+
+std::string TeBkUmLpqRouter::APP_NAME = "";
+std::string TeBkUmLpqRouter::TPE_FN_NAME = "";
+
+TeBkUmLpqRouter::TeBkUmLpqRouter() {
+	sqli = NULL;
+	if(APP_NAME=="") {
+		APP_NAME = CommonUtils::normalizeAppName("te-benchmark-um-pq");
+		TPE_FN_NAME = CommonUtils::getTpeFnName("tpe/fortunes.tpe", "te-benchmark-um-pq");
+	}
+}
+
+TeBkUmLpqRouter::~TeBkUmLpqRouter() {
+}
+
+LibpqDataSourceImpl* TeBkUmLpqRouter::getDb() {
+	if(sqli==NULL) {
+		sqli = static_cast<LibpqDataSourceImpl*>(DataSourceManager::getRawImpl("PostgreSQL-DSN", "te-benchmark-um-pq"));
+	}
+	return sqli;
 }
 }

+ 7 - 0
frameworks/C++/ffead-cpp/te-benchmark-um/config/cachememory.xml

@@ -0,0 +1,7 @@
+<caches>
+        <cache>
+                <init>TeBkUmRouter.updateCache</init>
+                <name>Memory-Cached</name>
+                <type>memory</type>
+        </cache>
+</caches>

+ 8 - 2
frameworks/C++/ffead-cpp/te-benchmark-um/include/TeBkUm.h

@@ -40,7 +40,7 @@
 #include "yuarel.h"
 #include "yuarel.h"
 #include "Router.h"
 #include "Router.h"
 
 
-typedef std::string (*TeBkUmTemplatePtr) (Context*);
+typedef void (*TeBkUmTemplatePtr) (Context*, std::string&);
 
 
 #pragma @Entity
 #pragma @Entity
 #pragma @Table name="fortune"
 #pragma @Table name="fortune"
@@ -70,6 +70,10 @@ public:
 class TeBkUmRouter : public Router {
 class TeBkUmRouter : public Router {
 	static const std::string HELLO_WORLD;
 	static const std::string HELLO_WORLD;
 	static std::string WORLD;
 	static std::string WORLD;
+
+	static std::string APP_NAME;
+	static std::string TPE_FN_NAME;
+
 	bool strToNum(const char* str, int len, int& ret);
 	bool strToNum(const char* str, int len, int& ret);
 	void db(TeBkUmWorld&);
 	void db(TeBkUmWorld&);
 	void queries(const char*, int, std::vector<TeBkUmWorld>&);
 	void queries(const char*, int, std::vector<TeBkUmWorld>&);
@@ -77,8 +81,10 @@ class TeBkUmRouter : public Router {
 	void cachedWorlds(const char*, int, std::vector<TeBkUmWorld>&);
 	void cachedWorlds(const char*, int, std::vector<TeBkUmWorld>&);
 	void getContext(HttpRequest* request, Context* context);
 	void getContext(HttpRequest* request, Context* context);
 public:
 public:
+	TeBkUmRouter();
+	virtual ~TeBkUmRouter();
 	void updateCache();
 	void updateCache();
-	void route(HttpRequest* req, HttpResponse* res, void* dlib, void* ddlib);
+	bool route(HttpRequest* req, HttpResponse* res, void* dlib, void* ddlib, SocketInterface* sif);
 };
 };
 
 
 #endif /* WEB_TE_BENCHMARK_UM_INCLUDE_TeBkUm_H_ */
 #endif /* WEB_TE_BENCHMARK_UM_INCLUDE_TeBkUm_H_ */

+ 30 - 13
frameworks/C++/ffead-cpp/te-benchmark-um/src/TeBkUm.cpp

@@ -187,23 +187,26 @@ void TeBkUmRouter::getContext(HttpRequest* request, Context* context) {
 	DataSourceInterface* sqli = DataSourceManager::getImpl();
 	DataSourceInterface* sqli = DataSourceManager::getImpl();
 
 
 	try {
 	try {
-		std::vector<TeBkUmFortune> flst = sqli->getAll<TeBkUmFortune>();
-		for(int i=0;i<(int)flst.size();i++)
+		std::vector<TeBkUmFortune> flstT = sqli->getAll<TeBkUmFortune>();
+		std::vector<TeBkUmFortune>* flst = new std::vector<TeBkUmFortune>;
+		flst->swap(flstT);
+
+		for(int i=0;i<(int)flst->size();i++)
 		{
 		{
-			std::string nm = flst.at(i).getMessage();
+			std::string nm = flst->at(i).getMessage();
 			CryptoHandler::sanitizeHtml(nm);
 			CryptoHandler::sanitizeHtml(nm);
-			flst.at(i).setMessage(nm);
+			flst->at(i).setMessage(nm);
 		}
 		}
 
 
 		TeBkUmFortune nf;
 		TeBkUmFortune nf;
 		nf.setId(0);
 		nf.setId(0);
 		nf.setMessage("Additional fortune added at request time.");
 		nf.setMessage("Additional fortune added at request time.");
-		flst.push_back(nf);
-		std::sort (flst.begin(), flst.end());
-		DataSourceManager::cleanImpl(sqli);
+		flst->push_back(nf);
+		std::sort (flst->begin(), flst->end());
+
+		context->insert(std::pair<std::string, void*>("fortunes", flst));
 
 
-		context->insert(std::pair<std::string, GenericObject>("fortunes", GenericObject()));
-		context->find("fortunes")->second << flst;
+		DataSourceManager::cleanImpl(sqli);
 	} catch(...) {
 	} catch(...) {
 		DataSourceManager::cleanImpl(sqli);
 		DataSourceManager::cleanImpl(sqli);
 		throw;
 		throw;
@@ -221,7 +224,7 @@ bool TeBkUmRouter::strToNum(const char* str, int len, int& ret) {
     return true;
     return true;
 }
 }
 
 
-void TeBkUmRouter::route(HttpRequest* req, HttpResponse* res, void* dlib, void* ddlib) {
+bool TeBkUmRouter::route(HttpRequest* req, HttpResponse* res, void* dlib, void* ddlib, SocketInterface* sif) {
 	//Timer t;
 	//Timer t;
 	//t.start();
 	//t.start();
 	std::string_view path = req->getPath();
 	std::string_view path = req->getPath();
@@ -279,12 +282,12 @@ void TeBkUmRouter::route(HttpRequest* req, HttpResponse* res, void* dlib, void*
 		Context ctx;
 		Context ctx;
 		getContext(req, &ctx);
 		getContext(req, &ctx);
 
 
-		std::string fname = "_tebenchmarkumtpefortunestpeemittTemplateHTML";
-		void* mkr = dlsym(ddlib, fname.c_str());
+		void* mkr = dlsym(ddlib, TPE_FN_NAME.c_str());
 		if(mkr!=NULL)
 		if(mkr!=NULL)
 		{
 		{
 			TeBkUmTemplatePtr f =  (TeBkUmTemplatePtr)mkr;
 			TeBkUmTemplatePtr f =  (TeBkUmTemplatePtr)mkr;
-			std::string msg = f(&ctx);
+			std::string msg;
+			f(&ctx, msg);
 			res->setContent(msg);
 			res->setContent(msg);
 			res->setContentType(ContentTypes::CONTENT_TYPE_TEXT_SHTML);
 			res->setContentType(ContentTypes::CONTENT_TYPE_TEXT_SHTML);
 			res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
 			res->setHTTPResponseStatus(HTTPResponseStatus::Ok);
@@ -325,4 +328,18 @@ void TeBkUmRouter::route(HttpRequest* req, HttpResponse* res, void* dlib, void*
 		res->setHTTPResponseStatus(HTTPResponseStatus::NotFound);
 		res->setHTTPResponseStatus(HTTPResponseStatus::NotFound);
 	}
 	}
 	res->setDone(true);
 	res->setDone(true);
+	return true;
+}
+
+std::string TeBkUmRouter::APP_NAME = "";
+std::string TeBkUmRouter::TPE_FN_NAME = "";
+
+TeBkUmRouter::TeBkUmRouter() {
+	if(APP_NAME=="") {
+		APP_NAME = CommonUtils::normalizeAppName("te-benchmark-um");
+		TPE_FN_NAME = CommonUtils::getTpeFnName("tpe/fortunes.tpe", "te-benchmark-um");
+	}
+}
+
+TeBkUmRouter::~TeBkUmRouter() {
 }
 }

+ 1 - 1
frameworks/C++/ffead-cpp/te-benchmark-um/src/autotools/Makefile.am

@@ -9,7 +9,7 @@ fprefix=../../../../${packageIdentifier}
 prefix=${abs_builddir}
 prefix=${abs_builddir}
 
 
 lib_LTLIBRARIES = libte_benchmark_um.la
 lib_LTLIBRARIES = libte_benchmark_um.la
-libte_benchmark_la_SOURCES = ../TeBkUmWorld.cpp \
+libte_benchmark_um_la_SOURCES = ../TeBkUmWorld.cpp \
 				../TeBkUm.cpp
 				../TeBkUm.cpp
 
 
 libte_benchmark_um_la_LDFLAGS = -no-undefined 
 libte_benchmark_um_la_LDFLAGS = -no-undefined