Browse Source

Spray fixed

mfirry 9 years ago
parent
commit
782a9102a0
100 changed files with 1921 additions and 533 deletions
  1. 24 3
      .travis.yml
  2. 2 1
      benchmark.cfg.example
  3. 2 2
      config/php.ini
  4. 7 2
      config/postgresql.conf
  5. 1 1
      deployment/vagrant-common/custom_motd.sh
  6. 2 2
      deployment/vagrant-development/README.md
  7. 1 0
      deployment/vagrant-development/Vagrantfile
  8. 1 1
      deployment/vagrant-production/README.md
  9. 2 0
      frameworks/C++/cpoll_cppsp/.gitignore
  10. 1 0
      frameworks/C++/ffead-cpp/.gitignore
  11. 1 0
      frameworks/C++/poco/.gitignore
  12. 78 0
      frameworks/C++/poco/benchmark.cpp
  13. 24 0
      frameworks/C++/poco/benchmark_config.json
  14. 7 0
      frameworks/C++/poco/setup.sh
  15. 1 0
      frameworks/C++/silicon/.gitignore
  16. 6 3
      frameworks/C++/silicon/CMakeLists.txt
  17. 28 4
      frameworks/C++/silicon/benchmark_config.json
  18. 0 137
      frameworks/C++/silicon/main.cc
  19. 11 0
      frameworks/C++/silicon/setup_lwan_mysql.sh
  20. 1 1
      frameworks/C++/silicon/setup_mhd_epoll_mysql.sh
  21. 1 1
      frameworks/C++/silicon/setup_mhd_tpc_mysql.sh
  22. 103 0
      frameworks/C++/silicon/techempower.hh
  23. 41 0
      frameworks/C++/silicon/techempower_lwan.cc
  24. 48 0
      frameworks/C++/silicon/techempower_microhttpd.cc
  25. 5 1
      frameworks/C++/ulib/README.md
  26. 14 14
      frameworks/C++/ulib/benchmark_config.json
  27. 7 2
      frameworks/C++/ulib/setup_json.sh
  28. 29 0
      frameworks/C++/ulib/setup_mongodb.sh
  29. 7 2
      frameworks/C++/ulib/setup_mysql.sh
  30. 7 2
      frameworks/C++/ulib/setup_plaintext.sh
  31. 1 1
      frameworks/C++/ulib/setup_postgres.sh
  32. 7 2
      frameworks/C++/ulib/setup_redis.sh
  33. 7 2
      frameworks/C++/ulib/setup_sqlite.sh
  34. 4 0
      frameworks/C++/ulib/source_code
  35. 1 1
      frameworks/C++/ulib/src/db.usp
  36. 1 1
      frameworks/C++/ulib/src/fortune.usp
  37. 81 0
      frameworks/C++/ulib/src/mdb.usp
  38. 89 0
      frameworks/C++/ulib/src/mfortune.usp
  39. 105 0
      frameworks/C++/ulib/src/mquery.usp
  40. 99 0
      frameworks/C++/ulib/src/mupdate.usp
  41. 15 29
      frameworks/C++/ulib/src/query.usp
  42. 2 3
      frameworks/C++/ulib/src/rdb.usp
  43. 9 22
      frameworks/C++/ulib/src/rquery.usp
  44. 1 14
      frameworks/C++/ulib/src/rupdate.usp
  45. 17 30
      frameworks/C++/ulib/src/update.usp
  46. 2 0
      frameworks/C++/wt/.gitignore
  47. 3 1
      frameworks/C/duda/.gitignore
  48. 1 0
      frameworks/C/libreactor/benchmark_config.json
  49. 2 0
      frameworks/C/libreactor/setup.sh
  50. 2 0
      frameworks/C/onion/.gitignore
  51. 1 1
      frameworks/CSharp/aspnet/setup_nginx.sh
  52. 1 1
      frameworks/CSharp/nancy/setup_nginx.sh
  53. 9 0
      frameworks/CSharp/revenj/.gitignore
  54. 29 0
      frameworks/CSharp/revenj/README.md
  55. 29 0
      frameworks/CSharp/revenj/Revenj.Bench.sln
  56. 32 0
      frameworks/CSharp/revenj/Revenj.Bench/Context.cs
  57. 154 0
      frameworks/CSharp/revenj/Revenj.Bench/RestService.cs
  58. 101 0
      frameworks/CSharp/revenj/Revenj.Bench/Revenj.Bench.csproj
  59. 9 0
      frameworks/CSharp/revenj/Revenj.Bench/model.dsl
  60. 30 0
      frameworks/CSharp/revenj/Revenj.Http.exe.config
  61. 49 0
      frameworks/CSharp/revenj/benchmark_config.json
  62. 3 0
      frameworks/CSharp/revenj/install.sh
  63. 75 0
      frameworks/CSharp/revenj/setup.ps1
  64. 43 0
      frameworks/CSharp/revenj/setup.sh
  65. 4 0
      frameworks/CSharp/revenj/source_code
  66. 1 1
      frameworks/CSharp/servicestack/setup_nginx.sh
  67. 1 1
      frameworks/CSharp/servicestack/setup_xsp.sh
  68. 4 4
      frameworks/Clojure/aleph/README.md
  69. 5 5
      frameworks/Clojure/aleph/hello/project.clj
  70. 1 1
      frameworks/Clojure/aleph/setup.sh
  71. 1 1
      frameworks/Clojure/compojure/README.md
  72. 2 2
      frameworks/Clojure/compojure/hello/project.clj
  73. 55 50
      frameworks/Clojure/compojure/hello/src/hello/handler.clj
  74. 2 2
      frameworks/Clojure/compojure/setup.sh
  75. 1 1
      frameworks/Clojure/http-kit/README.md
  76. 2 2
      frameworks/Clojure/http-kit/hello/project.clj
  77. 57 52
      frameworks/Clojure/http-kit/hello/src/hello/handler.clj
  78. 2 2
      frameworks/Clojure/http-kit/setup.sh
  79. 2 21
      frameworks/Clojure/luminus/README.md
  80. 6 6
      frameworks/Clojure/luminus/benchmark_config.json
  81. 3 1
      frameworks/Clojure/luminus/hello/.gitignore
  82. 4 2
      frameworks/Clojure/luminus/hello/README.md
  83. 10 0
      frameworks/Clojure/luminus/hello/env/dev/clj/hello/dev_middleware.clj
  84. 11 0
      frameworks/Clojure/luminus/hello/env/dev/clj/hello/env.clj
  85. 0 34
      frameworks/Clojure/luminus/hello/env/dev/clj/hello/repl.clj
  86. 15 0
      frameworks/Clojure/luminus/hello/env/dev/clj/user.clj
  87. 5 0
      frameworks/Clojure/luminus/hello/env/dev/resources/config.edn
  88. 25 0
      frameworks/Clojure/luminus/hello/env/dev/resources/log4j.properties
  89. 8 0
      frameworks/Clojure/luminus/hello/env/prod/clj/hello/env.clj
  90. 3 0
      frameworks/Clojure/luminus/hello/env/prod/resources/config.edn
  91. 25 0
      frameworks/Clojure/luminus/hello/env/prod/resources/log4j.properties
  92. 3 0
      frameworks/Clojure/luminus/hello/env/test/resources/config.edn
  93. 56 39
      frameworks/Clojure/luminus/hello/project.clj
  94. 34 0
      frameworks/Clojure/luminus/hello/resources/docs/docs.md
  95. 28 1
      frameworks/Clojure/luminus/hello/resources/public/css/screen.css
  96. 0 0
      frameworks/Clojure/luminus/hello/resources/public/favicon.ico
  97. 9 15
      frameworks/Clojure/luminus/hello/resources/sql/queries.sql
  98. 4 0
      frameworks/Clojure/luminus/hello/resources/templates/about.html
  99. 56 0
      frameworks/Clojure/luminus/hello/resources/templates/error.html
  100. 0 3
      frameworks/Clojure/luminus/hello/resources/templates/home.html

+ 24 - 3
.travis.yml

@@ -25,6 +25,7 @@ env:
     - "TESTDIR=CSharp/evhttp-sharp"
     ## - "TESTDIR=CSharp/HttpListener"
     - "TESTDIR=CSharp/nancy"
+    - "TESTDIR=CSharp/revenj"
     - "TESTDIR=CSharp/servicestack"
     - "TESTDIR=C++/cpoll_cppsp"
     - "TESTDIR=C++/silicon"
@@ -32,6 +33,7 @@ env:
     - "TESTDIR=C++/ulib"
     - "TESTDIR=C++/wt"
     - "TESTDIR=C++/ffead-cpp"
+    - "TESTDIR=C++/poco"
     - "TESTDIR=Clojure/compojure"
     - "TESTDIR=Clojure/http-kit"
     - "TESTDIR=Clojure/luminus"
@@ -39,6 +41,7 @@ env:
     - "TESTDIR=Clojure/aleph"
     - "TESTDIR=Crystal/crystal-raw"
     - "TESTDIR=Crystal/moonshine"
+    - "TESTDIR=Crystal/kemal"
     - "TESTDIR=D/vibed"
     - "TESTDIR=Dart/dart-raw"
     - "TESTDIR=Dart/redstone"
@@ -56,9 +59,10 @@ env:
     - "TESTDIR=Go/fasthttp-mysql"
     - "TESTDIR=Go/fasthttp-postgresql"
     - "TESTDIR=Go/gin"
-    - "TESTDIR=Go/go-raw"
     - "TESTDIR=Go/goji"
-    - "TESTDIR=Go/go-raw-mongodb"
+    - "TESTDIR=Go/go-std-mongodb"
+    - "TESTDIR=Go/go-std-mysql"
+    - "TESTDIR=Go/go-std-postgresql"
     - "TESTDIR=Go/revel"
     - "TESTDIR=Go/revel-jet"
     - "TESTDIR=Go/revel-qbs"
@@ -67,7 +71,10 @@ env:
     - "TESTDIR=Haskell/snap"
     - "TESTDIR=Haskell/wai"
     - "TESTDIR=Haskell/yesod"
+    - "TESTDIR=Haskell/spock"
     - "TESTDIR=Java/activeweb"
+    - "TESTDIR=Java/baratine"
+    - "TESTDIR=Java/bayou"
     - "TESTDIR=Java/comsat-servlet"
     - "TESTDIR=Java/comsat-webactors"
     - "TESTDIR=Java/curacao"
@@ -78,24 +85,31 @@ env:
     - "TESTDIR=Java/jawn"
     - "TESTDIR=Java/jetty-servlet"
     - "TESTDIR=Java/jetty"
+    - "TESTDIR=Java/jooby"
     - "TESTDIR=Java/netty"
     - "TESTDIR=Java/ninja-standalone"
+    - "TESTDIR=Java/officefloor"
+    - "TESTDIR=Java/permeagility"
     - "TESTDIR=Java/play1"
     - "TESTDIR=Java/play1siena"
     - "TESTDIR=Java/play2-java"
     - "TESTDIR=Java/rapidoid"
     - "TESTDIR=Java/restexpress"
+    - "TESTDIR=Java/revenj"
     - "TESTDIR=Java/servlet"
     - "TESTDIR=Java/servlet3-cass"
-    - "TESTDIR=Java/servlet-dsl"
     - "TESTDIR=Java/spark"
     - "TESTDIR=Java/sabina"
     - "TESTDIR=Java/spring"
     - "TESTDIR=Java/tapestry"
     - "TESTDIR=Java/undertow"
     - "TESTDIR=Java/undertow-edge"
+    - "TESTDIR=Java/undertow-jersey-c3p0"
+    - "TESTDIR=Java/undertow-jersey-hikaricp"
     - "TESTDIR=Java/vertx"
+    - "TESTDIR=Java/vertx-web"
     - "TESTDIR=Java/wicket"
+    - "TESTDIR=Java/beyondj"
     - "TESTDIR=Java/wildfly-ee7"
     - "TESTDIR=JavaScript/express"
     - "TESTDIR=JavaScript/hapi"
@@ -171,6 +185,7 @@ env:
     - "TESTDIR=Scala/akka-http"
     - "TESTDIR=Scala/colossus"
     - "TESTDIR=Scala/finagle"
+    - "TESTDIR=Scala/fintrospect"
     - "TESTDIR=Scala/lift-stateless"
     - "TESTDIR=Scala/plain"
     - "TESTDIR=Scala/play2-scala"
@@ -204,6 +219,7 @@ addons:
       - redis-server
 
 before_script:
+  - sudo sysctl -w net.core.somaxconn=65535
   - sudo ./config/travis_mysql_setup.sh
   - mysql -uroot < config/create.sql
   - sudo ./config/create-redis.sh
@@ -211,3 +227,8 @@ before_script:
 script:
   # Pick one test in this directory and verify
   - time ./toolset/run-ci.py verify "$TESTDIR"
+
+cache:
+  directories:
+    - $HOME/.m2/repository
+    - $HOME/.cache/pip

+ 2 - 1
benchmark.cfg.example

@@ -20,7 +20,6 @@ concurrency_levels=[8, 16, 32, 64, 128, 256]
 query_levels=[1, 5,10,15,20]
 threads=8
 mode=benchmark
-name=ec2
 os=linux
 password_prompt=False
 server_host=127.0.0.1
@@ -28,3 +27,5 @@ sleep=60
 test=None
 type=all
 verbose=True
+clean=False
+clean_all=False

+ 2 - 2
config/php.ini

@@ -869,8 +869,8 @@ default_socket_timeout = 60
 zend_extension=opcache.so
 extension=redis.so
 extension=phalcon.so
-extension=yaf.so
-extension=mongo.so
+;extension=yaf.so
+extension=mongodb.so
 ;extension=php_bz2.dll
 ;extension=php_curl.dll
 ;extension=php_fileinfo.dll

+ 7 - 2
config/postgresql.conf

@@ -109,7 +109,7 @@ ssl = false                             # (change requires restart)
 # details: http://www.postgresql.org/docs/9.4/static/runtime-config-resource.html
 # http://www.postgresql.org/docs/9.4/static/runtime-config-wal.html
 # http://www.postgresql.org/docs/9.4/static/runtime-config-query.html
-shared_buffers = 2GB                    # min 128kB
+shared_buffers = 256MB                    # min 128kB
 work_mem = 64MB                                # min 64kB
 maintenance_work_mem = 512MB            # min 1MB
 checkpoint_segments = 64
@@ -166,7 +166,12 @@ random_page_cost = 2
 #wal_level = minimal			# minimal, archive, or hot_standby
 					# (change requires restart)
 #fsync = on				# turns forced synchronization on or off
-#synchronous_commit = on		# synchronization level; on, off, or local
+
+# WARNING: disabling synchronous commit may be dangerous in certain cases.
+# See http://www.postgresql.org/docs/current/static/runtime-config-wal.html
+# for details.
+synchronous_commit = off
+
 #wal_sync_method = fsync		# the default is the first option
 					# supported by the operating system:
 					#   open_datasync

+ 1 - 1
deployment/vagrant-common/custom_motd.sh

@@ -6,7 +6,7 @@ echo ""
 echo "  To get started, perhaps try this:"
 echo "    \$ cd FrameworkBenchmarks"
 echo "    \$ toolset/run-tests.py --install server --test go"
-echo "    \$ cat results/ec2/latest/logs/go/out.txt"
+echo "    \$ cat results/latest/logs/go/out.txt"
 echo ""
 echo "  You can get lots of help:"
 echo "    \$ toolset/run-tests.py --help"

+ 2 - 2
deployment/vagrant-development/README.md

@@ -51,7 +51,7 @@ Welcome to the FrameworkBenchmarks project!
 To get started, perhaps try this:
    $ cd FrameworkBenchmarks
    $ toolset/run-tests.py --install server --test go
-   $ cat results/ec2/latest/logs/go/out.txt
+   $ cat results/latest/logs/go/out.txt
 
 You can get lots of help:
    $ toolset/run-tests.py --help
@@ -71,7 +71,7 @@ usernames, or private key files, as so:
     <log for installing software needed for go test>
     <log for launching go framework>
     <log for verifying go framework meets requirements>
-    $ cat results/ec2/latest/logs/go/out.txt
+    $ cat results/latest/logs/go/out.txt
     <log with stdout from framework go>
 
 # Using Amazon-powered Virtual Machine

+ 1 - 0
deployment/vagrant-development/Vagrantfile

@@ -25,3 +25,4 @@ Vagrant.configure("2") do |config|
   provider_aws(config, 'integrated')
   
 end
+

+ 1 - 1
deployment/vagrant-production/README.md

@@ -46,7 +46,7 @@ Welcome to the FrameworkBenchmarks project!
 To get started, perhaps try this:
    $ cd FrameworkBenchmarks
    $ toolset/run-tests.py --install server --test go
-   $ cat results/ec2/latest/logs/go/out.txt
+   $ cat results/latest/logs/go/out.txt
 
 You can get lots of help:
    $ toolset/run-tests.py --help

+ 2 - 0
frameworks/C++/cpoll_cppsp/.gitignore

@@ -0,0 +1,2 @@
+/www/*.so
+/www/*.txt

+ 1 - 0
frameworks/C++/ffead-cpp/.gitignore

@@ -0,0 +1 @@
+/ffead-cpp-2.0/

+ 1 - 0
frameworks/C++/poco/.gitignore

@@ -0,0 +1 @@
+/poco

+ 78 - 0
frameworks/C++/poco/benchmark.cpp

@@ -0,0 +1,78 @@
+#include <Poco/Net/ServerSocket.h>
+#include <Poco/Net/HTTPServer.h>
+#include <Poco/Net/HTTPRequestHandler.h>
+#include <Poco/Net/HTTPRequestHandlerFactory.h>
+#include <Poco/Net/HTTPResponse.h>
+#include <Poco/Net/HTTPServerRequest.h>
+#include <Poco/Net/HTTPServerResponse.h>
+#include <Poco/Util/ServerApplication.h>
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+#define PLAIN_URL_PATH       "/plaintext"
+#define PLAIN_CONTENT_TYPE   "text/plain"
+#define RES_BODY             "Hello, World!"
+#define SERVER_NAME          "poco"
+
+using namespace Poco::Net;
+using namespace Poco::Util;
+using namespace std;
+
+class MyRequestHandler : public HTTPRequestHandler {
+public:
+    virtual void handleRequest(HTTPServerRequest &req, HTTPServerResponse &resp) {
+        resp.setStatusAndReason(HTTPResponse::HTTP_OK, "OK");
+        resp.setContentType(PLAIN_CONTENT_TYPE);
+        resp.add("Server", SERVER_NAME);
+        resp.sendBuffer(RES_BODY, sizeof(RES_BODY)-1);
+        return;
+    }
+};
+
+class NotFoundRequestHandler : public HTTPRequestHandler {
+public:
+    virtual void handleRequest(HTTPServerRequest &req, HTTPServerResponse &resp) {
+        resp.setStatusAndReason(HTTPResponse::HTTP_NOT_FOUND, "NOT_FOUND");
+        resp.setContentType(PLAIN_CONTENT_TYPE);
+        resp.add("Server", SERVER_NAME);
+        resp.sendBuffer("", 0);
+        return;
+    }
+};
+
+class MyRequestHandlerFactory : public HTTPRequestHandlerFactory {
+public:
+    virtual HTTPRequestHandler* createRequestHandler(const HTTPServerRequest &req) {
+        if (req.getMethod() == "GET" && req.getURI() == PLAIN_URL_PATH)
+            return new MyRequestHandler;
+        else
+            return new NotFoundRequestHandler;
+    }
+};
+
+class MyServerApp : public ServerApplication {
+protected:
+    int main(const vector<string> &args) {
+        HTTPServerParams* hsp = new HTTPServerParams;
+        hsp->setMaxThreads(stoi(args[1]));
+        hsp->setKeepAlive(true);
+        HTTPServer s(new MyRequestHandlerFactory, ServerSocket(stoi(args[0]), 4000), hsp);
+        s.start();
+        waitForTerminationRequest();
+        s.stop();
+        return Application::EXIT_OK;
+    }
+};
+
+int main(int argc, char** argv) {
+    if (argc != 3) {
+        std::cerr << "Usage: " << argv[0] << " port nthreads" << std::endl;
+        return 1;
+    }
+    
+    MyServerApp app;
+    return app.run(argc, argv);
+}
+

+ 24 - 0
frameworks/C++/poco/benchmark_config.json

@@ -0,0 +1,24 @@
+{
+  "framework": "poco",
+  "tests": [{
+    "default": {
+      "setup_file": "setup",
+      "plaintext_url": "/plaintext",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Platform",
+      "database": "none",
+      "framework": "POCO",
+      "language": "C++",
+      "orm": "Raw",
+      "platform": "POCO",
+      "webserver": "poco",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "POCO",
+      "notes": "",
+      "versus": ""
+    }
+  }]
+}
+

+ 7 - 0
frameworks/C++/poco/setup.sh

@@ -0,0 +1,7 @@
+#!/bin/bash
+
+fw_depends poco
+
+g++-4.8 -O3 -DNDEBUG -std=c++0x -o poco benchmark.cpp -I$POCO_HOME/Foundation/include -I$POCO_HOME/Util/include -I$POCO_HOME/Net/include -L$POCO_HOME/lib/Linux/x86_64 -lPocoNet -lPocoUtil -lPocoFoundation -lPocoXML -lPocoJSON
+./poco 8080 $MAX_THREADS
+

+ 1 - 0
frameworks/C++/silicon/.gitignore

@@ -0,0 +1 @@
+/build/

+ 6 - 3
frameworks/C++/silicon/CMakeLists.txt

@@ -6,11 +6,14 @@ include_directories($ENV{IROOT}/include $ENV{MICROHTTPD_HOME}/include)
 
 link_directories($ENV{IROOT}/lib $ENV{MICROHTTPD_HOME}/lib)
 
-add_definitions(-std=c++14  -ftemplate-depth=512 -DNDEBUG -O3)
+add_definitions(-std=c++14 -ftemplate-depth=1024 -DNDEBUG -O3)
 
-add_executable(silicon_tpc_mysql main.cc)
+add_executable(silicon_tpc_mysql techempower_microhttpd.cc)
 target_link_libraries(silicon_tpc_mysql microhttpd mysqlclient)
 
-add_executable(silicon_epoll_mysql main.cc)
+add_executable(silicon_epoll_mysql techempower_microhttpd.cc)
 set_target_properties(silicon_epoll_mysql PROPERTIES COMPILE_FLAGS "-DTFB_USE_EPOLL")
 target_link_libraries(silicon_epoll_mysql microhttpd mysqlclient)
+
+add_executable(silicon_lwan_mysql techempower_lwan.cc)
+target_link_libraries(silicon_lwan_mysql mysqlclient lwan-common curl z pthread dl)

+ 28 - 4
frameworks/C++/silicon/benchmark_config.json

@@ -2,7 +2,7 @@
   "framework": "silicon",
   "tests": [{
     "default": {
-      "setup_file": "setup_tpc_mysql",
+      "setup_file": "setup_mhd_tpc_mysql",
       "json_url"       : "/json",
       "db_url"         : "/db",
       "query_url"      : "/queries?queries=",
@@ -17,7 +17,7 @@
       "language": "C++",
       "orm": "Full",
       "platform": "Silicon",
-      "webserver": "None",
+      "webserver": "microhttpd",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "silicon-tpc-mysql",
@@ -25,7 +25,7 @@
       "versus": ""
     },
     "epoll-mysql": {
-      "setup_file": "setup_epoll_mysql",
+      "setup_file": "setup_mhd_epoll_mysql",
       "json_url"       : "/json",
       "db_url"         : "/db",
       "query_url"      : "/queries?queries=",
@@ -40,12 +40,36 @@
       "language": "C++",
       "orm": "Full",
       "platform": "Silicon",
-      "webserver": "None",
+      "webserver": "microhttpd",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "silicon-epoll-mysql",
       "notes": "",
       "versus": ""
+    },
+    "lwan-mysql": {
+      "setup_file": "setup_lwan_mysql",
+      "json_url"       : "/json",
+      "db_url"         : "/db",
+      "query_url"      : "/queries?queries=",
+      "fortune_url"    : "/fortunes",
+      "update_url"     : "/updates?queries=",
+      "plaintext_url"  : "/plaintext",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Micro",
+      "database": "MySQL",
+      "framework": "silicon",
+      "language": "C++",
+      "orm": "Full",
+      "platform": "Silicon",
+      "webserver": "Lwan",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "silicon-lwan-mysql",
+      "notes": "",
+      "versus": ""
     }
+    
   }]
 }

+ 0 - 137
frameworks/C++/silicon/main.cc

@@ -1,137 +0,0 @@
-#include <algorithm>
-#include <unistd.h>
-#include <iostream>
-#include <silicon/backends/mhd.hh>
-#include <silicon/api.hh>
-#include <silicon/middlewares/mysql_connection.hh>
-#include <silicon/middlewares/mysql_orm.hh>
-#include "symbols.hh"
-
-using namespace s;
-using namespace sl;
-
-typedef decltype(D(_id(_auto_increment, _primary_key) = int(),
-                   _randomNumber = int())) random_number;
-
-typedef decltype(D(_id(_auto_increment, _primary_key) = int(),
-                   _message = std::string())) fortune;
-
-typedef mysql_orm_factory<random_number> rn_orm_factory;
-typedef mysql_orm<random_number> rn_orm;
-
-typedef mysql_orm_factory<fortune> fortune_orm_factory;
-typedef mysql_orm<fortune> fortune_orm;
-
-std::string escape_html_entities(const std::string& data)
-{
-    std::string buffer;
-    buffer.reserve(data.size());
-    for(size_t pos = 0; pos != data.size(); ++pos) {
-        switch(data[pos]) {
-            case '&':  buffer.append("&amp;");       break;
-            case '\"': buffer.append("&quot;");      break;
-            case '\'': buffer.append("&apos;");      break;
-            case '<':  buffer.append("&lt;");        break;
-            case '>':  buffer.append("&gt;");        break;
-            default:   buffer.append(&data[pos], 1); break;
-        }
-    }
-    return std::move(buffer);
-}
-
-int main(int argc, char* argv[])
-{
-
-  if (argc != 4)
-  {
-    std::cerr << "Usage: " << argv[0] << " mysql_host port nthreads" << std::endl;
-    return 1;
-  }
-  
-  auto hello_api = make_api(
-
-    _plaintext = [] () { return response(_content_type = "text/plain",
-                                         _body = "Hello, World!"); },
-
-    _json = [] () { return response(_content_type = "application/json",
-                                    _body = D(_message = "Hello, World!")); },
-                        
-    _db = [] (rn_orm& orm) {
-      random_number r;
-      orm.find_by_id(1245, r);
-      return response(_content_type = "application/json",
-                      _body = r);
-    },
-
-    _queries = [] (rn_orm& orm, get_parameters& get_params) {
-      int N = atoi(get_params["queries"].c_str());
-      N = std::max(1, std::min(N, 500));
-
-      std::vector<random_number> qs(N);
-      for (int i = 0; i < N; i++)
-        orm.find_by_id(1 + rand() % 9999, qs[i]);
-      return response(_content_type = "application/json",
-                      _body = std::move(qs));
-    },
-
-    _updates = [] (rn_orm& orm, get_parameters& get_params) {
-      int N = atoi(get_params["queries"].c_str());
-      N = std::max(1, std::min(N, 500));
-
-      std::vector<random_number> qs(N);
-      for (int i = 0; i < N; i++)
-      {
-        orm.find_by_id(1 + rand() % 9999, qs[i]);
-        qs[i].randomNumber = 1 + rand() % 9999;
-        orm.update(qs[i]);
-      }
-      return response(_content_type = "application/json",
-                      _body = std::move(qs));
-    },
-  
-    _fortunes = [] (fortune_orm& orm) {
-      std::vector<fortune> table;
-      orm.forall([&] (fortune& f) { table.push_back(f); });
-      table.push_back(fortune(0, "Additional fortune added at request time."));
-
-      std::sort(table.begin(), table.end(),
-                [] (const fortune& a, const fortune& b) { return a.message < b.message; });
-
-      std::stringstream ss;
-
-      ss << "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>";
-      for(auto& f : table)
-        ss << "<tr><td>" << f.id << "</td><td>" << escape_html_entities(f.message) << "</td></tr>";
-      ss << "</table></body></html>";
-
-      return response(_content_type = "text/html",
-                      _body = ss.str());
-    }
-  
-    ).bind_factories(
-      mysql_connection_factory(argv[1], "benchmarkdbuser", "benchmarkdbpass", "hello_world"),
-      fortune_orm_factory("Fortune"),
-      rn_orm_factory("World")
-      );
-  
-  try
-  {
-
-    // Start the server.
-    sl::mhd_json_serve(hello_api, atoi(argv[2])
-#ifdef TFB_USE_EPOLL
-                       , _linux_epoll, _nthreads = atoi(argv[3])
-#else
-                       , _one_thread_per_connection
-#endif
-      );
-  }
-  catch (std::exception& e)
-  {
-    std::cerr << e.what() << std::endl;
-  }
-  catch (sl::error::error& e)
-  {
-    std::cerr << e.what() << std::endl;
-  }
-}

+ 11 - 0
frameworks/C++/silicon/setup_lwan_mysql.sh

@@ -0,0 +1,11 @@
+#! /bin/bash
+
+fw_depends silicon lwan
+
+rm -rf build
+mkdir build
+cd build
+cmake .. -DCMAKE_CXX_COMPILER=clang++-3.5
+make silicon_lwan_mysql
+
+$TROOT/build/silicon_lwan_mysql ${DBHOST} 8080 &

+ 1 - 1
frameworks/C++/silicon/setup_epoll_mysql.sh → frameworks/C++/silicon/setup_mhd_epoll_mysql.sh

@@ -5,7 +5,7 @@ fw_depends silicon microhttpd
 rm -rf build
 mkdir build
 cd build
-cmake .. -DCMAKE_CXX_COMPILER=g++-4.9
+cmake .. -DCMAKE_CXX_COMPILER=clang++-3.5
 make silicon_epoll_mysql
 
 $TROOT/build/silicon_epoll_mysql ${DBHOST} 8080 ${MAX_THREADS} &

+ 1 - 1
frameworks/C++/silicon/setup_tpc_mysql.sh → frameworks/C++/silicon/setup_mhd_tpc_mysql.sh

@@ -5,7 +5,7 @@ fw_depends silicon microhttpd
 rm -rf build
 mkdir build
 cd build
-cmake .. -DCMAKE_CXX_COMPILER=g++-4.9
+cmake .. -DCMAKE_CXX_COMPILER=clang++-3.5
 make silicon_tpc_mysql
 
 $TROOT/build/silicon_tpc_mysql ${DBHOST} 8080 ${MAX_THREADS} &

+ 103 - 0
frameworks/C++/silicon/techempower.hh

@@ -0,0 +1,103 @@
+#include <unistd.h>
+#include <iostream>
+#include <silicon/api.hh>
+#include <silicon/middleware_factories.hh>
+#include <silicon/middlewares/mysql_connection.hh>
+#include <silicon/middlewares/mysql_orm.hh>
+#include "symbols.hh"
+
+using namespace s;
+using namespace sl;
+
+typedef decltype(D(_id(_auto_increment, _primary_key) = int(),
+                   _randomNumber = int())) random_number;
+
+typedef decltype(D(_id(_auto_increment, _primary_key) = int(),
+                   _message = std::string())) fortune;
+
+typedef mysql_orm_factory<random_number> rn_orm_factory;
+typedef mysql_orm<random_number> rn_orm;
+
+typedef mysql_orm_factory<fortune> fortune_orm_factory;
+typedef mysql_orm<fortune> fortune_orm;
+
+
+std::string escape_html_entities(std::string& data)
+{
+    std::string buffer;
+    buffer.reserve(data.size());
+    for(size_t pos = 0; pos != data.size(); ++pos) {
+        switch(data[pos]) {
+            case '&':  buffer.append("&amp;");       break;
+            case '\"': buffer.append("&quot;");      break;
+            case '\'': buffer.append("&apos;");      break;
+            case '<':  buffer.append("&lt;");        break;
+            case '>':  buffer.append("&gt;");        break;
+            default:   buffer.append(&data[pos], 1); break;
+        }
+    }
+    return std::move(buffer);
+}
+
+auto techempower_api = http_api(
+
+
+  GET / _plaintext = [] () { return response(_content_type = string_ref("text/plain"),
+                                       _body = string_ref("Hello, World!")); },
+
+  GET / _json = [] () { return response(_content_type = string_ref("application/json"),
+                                  _body = D(_message = string_ref("Hello, World!"))); },
+                        
+  GET / _db = [] (rn_orm& orm) {
+    random_number r;
+    orm.find_by_id(1245, r);
+    return response(_content_type = "application/json",
+                    _body = r);
+  },
+
+  GET / _queries * get_parameters(_queries = optional(std::string("1"))) = [] (auto param, rn_orm& orm) {
+    int N = atoi(param.queries.c_str());
+    N = std::max(1, std::min(N, 500));
+
+    std::vector<random_number> qs(N);
+    for (int i = 0; i < N; i++)
+      orm.find_by_id(1 + rand() % 9999, qs[i]);
+    return response(_content_type = "application/json",
+                    _body = std::move(qs));
+  },
+
+  GET / _updates * get_parameters(_queries = optional(std::string("1"))) = [] (auto param, rn_orm& orm) {
+    int N = atoi(param.queries.c_str());
+    N = std::max(1, std::min(N, 500));
+
+    std::vector<random_number> qs(N);
+    for (int i = 0; i < N; i++)
+    {
+      orm.find_by_id(1 + rand() % 9999, qs[i]);
+      qs[i].randomNumber = 1 + rand() % 9999;
+      orm.update(qs[i]);
+    }
+    return response(_content_type = "application/json",
+                    _body = std::move(qs));
+  },
+  
+  GET / _fortunes = [] (fortune_orm& orm) {
+    std::vector<fortune> table;
+    orm.forall([&] (fortune& f) { table.push_back(f); });
+    table.push_back(fortune(0, "Additional fortune added at request time."));
+
+    std::sort(table.begin(), table.end(),
+              [] (const fortune& a, const fortune& b) { return a.message < b.message; });
+
+    std::stringstream ss;
+
+    ss << "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>";
+    for(auto& f : table)
+      ss << "<tr><td>" << f.id << "</td><td>" << escape_html_entities(f.message) << "</td></tr>";
+    ss << "</table></body></html>";
+
+    return response(_content_type = "text/html; charset=utf-8",
+                    _body = ss.str());
+  }
+  
+  );

+ 41 - 0
frameworks/C++/silicon/techempower_lwan.cc

@@ -0,0 +1,41 @@
+#include <silicon/backends/lwan.hh>
+
+#include "techempower.hh"
+
+using namespace s;
+using namespace sl;
+
+int main(int argc, char* argv[])
+{
+  if (argc != 3)
+  {
+    std::cerr << "Usage: " << argv[0] << " mysql_host port" << std::endl;
+    return 1;
+  }
+
+  auto techempower_middlewares = middleware_factories(
+    mysql_connection_factory(argv[1], "benchmarkdbuser", "benchmarkdbpass", "hello_world"),
+    fortune_orm_factory("Fortune"),
+    rn_orm_factory("World")
+    );
+  
+  try
+  {
+
+    // Write the pid.
+    std::ofstream pidfile(argv[3]);
+    pidfile << getpid() << std::endl;
+    pidfile.close();
+
+    // Start the server.
+    sl::lwan_json_serve(techempower_api, techempower_middlewares, atoi(argv[2]));
+  }
+  catch (std::exception& e)
+  {
+    std::cerr << e.what() << std::endl;
+  }
+  catch (sl::error::error& e)
+  {
+    std::cerr << e.what() << std::endl;
+  }
+}

+ 48 - 0
frameworks/C++/silicon/techempower_microhttpd.cc

@@ -0,0 +1,48 @@
+#include <silicon/backends/mhd.hh>
+
+#include "techempower.hh"
+
+using namespace s;
+using namespace sl;
+
+int main(int argc, char* argv[])
+{
+
+  if (argc != 4)
+  {
+    std::cerr << "Usage: " << argv[0] << " mysql_host port nthreads" << std::endl;
+    return 1;
+  }
+
+  auto techempower_middlewares = middleware_factories(
+    mysql_connection_factory(argv[1], "benchmarkdbuser", "benchmarkdbpass", "hello_world"),
+    fortune_orm_factory("Fortune"),
+    rn_orm_factory("World")
+    );
+  
+  try
+  {
+    // Write the pid.
+    std::ofstream pidfile(argv[3]);
+    pidfile << getpid() << std::endl;
+    pidfile.close();
+
+    // Start the server.
+    sl::mhd_json_serve(techempower_api, techempower_middlewares, atoi(argv[2]), _blocking
+#ifdef TFB_USE_EPOLL
+                       , _linux_epoll, _nthreads = atoi(argv[3])
+#else
+                       , _one_thread_per_connection
+#endif
+      );
+    
+  }
+  catch (std::exception& e)
+  {
+    std::cerr << e.what() << std::endl;
+  }
+  catch (sl::error::error& e)
+  {
+    std::cerr << e.what() << std::endl;
+  }
+}

+ 5 - 1
frameworks/C++/ulib/README.md

@@ -10,21 +10,25 @@ This is the [ULib](http://stefanocasazza.github.io/ULib/) portion of a [benchmar
 
 * [Database test source (SQL)](src/db.usp)
 * [Database test source (REDIS)](src/rdb.usp)
+* [Database test source (MONGODB)](src/mdb.usp)
 
 ### Variable Query Test
 
 * [Variable Query test source (SQL)](src/query.usp)
 * [Variable Query test source (REDIS)](src/rquery.usp)
+* [Variable Query test source (MONGODB)](src/mquery.usp)
 
 ### Fortune Query Test
 
 * [Fortune Query test source (SQL)](src/fortune.usp)
 * [Fortune Query test source (REDIS)](src/rfortune.usp)
+* [Fortune Query test source (MONGODB)](src/mfortune.usp)
 
 ### Variable Query (update) Test
 
 * [Variable Query (update) test source (SQL)](src/update.usp)
 * [Variable Query (update) test source (REDIS)](src/rupdate.usp)
+* [Variable Query (update) test source (MONGODB)](src/mupdate.usp)
 
 ### Plaintext Test
 
@@ -80,7 +84,7 @@ Content-Type: application/json
 HTTP/1.1 200 OK
 Date: Thu, 03 Jul 2014 10:14:51 GMT
 Server: ULib 
-Content-Type: text/html
+Content-Type: text/html; charset=UTF-8
 Content-Length: 1227
 
 <!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><tr><td>11</td><td>&lt;script&gt;alert(&quot;This should not be displayed in a browser alert box.&quot;);&lt;/script&gt;</td></tr><tr><td>4</td><td>A bad random number generator: 1, 1, 1, 1, 1, 4.33e+67, 1, 1, 1</td></tr><tr><td>5</td><td>A computer program does what you tell it to do, not what you want it to do.</td></tr><tr><td>2</td><td>A computer scientist is someone who fixes things that aren&apos;t broken.</td></tr><tr><td>8</td><td>A list is only as strong as its weakest link. — Donald Knuth</td></tr><tr><td>0</td><td>Additional fortune added at request time.</td></tr><tr><td>3</td><td>After enough decimal places, nobody gives a damn.</td></tr><tr><td>7</td><td>Any program that runs right is obsolete.</td></tr><tr><td>10</td><td>Computers make very fast, very accurate mistakes.</td></tr><tr><td>6</td><td>Emacs is a nice operating system, but I prefer UNIX. — Tom Christaensen</td></tr><tr><td>9</td><td>Feature: A bug with seniority.</td></tr><tr><td>1</td><td>fortune: No such file or directory</td></tr><tr><td>12</td><td>フレームワークのベンチマーク</td></tr></table></body></html>

+ 14 - 14
frameworks/C++/ulib/benchmark_config.json

@@ -12,7 +12,7 @@
       "language": "C++",
       "orm": "Micro",
       "platform": "ULib",
-      "webserver": "userver_tcp",
+      "webserver": "ULib",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "ULib",
@@ -30,7 +30,7 @@
       "language": "C++",
       "orm": "Micro",
       "platform": "ULib",
-      "webserver": "userver_tcp",
+      "webserver": "ULib",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "ULib",
@@ -51,7 +51,7 @@
       "language": "C++",
       "orm": "Micro",
       "platform": "ULib",
-      "webserver": "userver_tcp",
+      "webserver": "ULib",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "ULib-mysql",
@@ -72,7 +72,7 @@
       "language": "C++",
       "orm": "Micro",
       "platform": "ULib",
-      "webserver": "userver_tcp",
+      "webserver": "ULib",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "ULib-postgres",
@@ -92,31 +92,31 @@
       "language": "C++",
       "orm": "Micro",
       "platform": "ULib",
-      "webserver": "userver_tcp",
+      "webserver": "ULib",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "ULib-sqlite",
       "notes": "",
       "versus": ""
     },
-    "redis": {
-      "setup_file": "setup_redis",
-      "db_url": "/rdb",
-      "query_url": "/rquery?queries=",
-      "fortune_url": "/rfortune",
-      "update_url": "/rupdate?queries=",
+    "mongodb": {
+      "setup_file": "setup_mongodb",
+      "db_url": "/mdb",
+      "query_url": "/mquery?queries=",
+      "fortune_url": "/mfortune",
+      "update_url": "/mupdate?queries=",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Platform",
-      "database": "Redis",
+      "database": "MongoDB",
       "framework": "ULib",
       "language": "C++",
       "orm": "Micro",
       "platform": "ULib",
-      "webserver": "userver_tcp",
+      "webserver": "ULib",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "ULib-redis",
+      "display_name": "ULib-mongodb",
       "notes": "",
       "versus": ""
     }

+ 7 - 2
frameworks/C++/ulib/setup_json.sh

@@ -2,7 +2,12 @@
 
 fw_depends ulib
 
-MAX_THREADS=$((2 * $MAX_THREADS))
+# Travis is broken
+if [ "$TRAVIS" != "true" ]; then
+MAX_THREADS=$(( 3 * $MAX_THREADS / 2 ))
+else
+MAX_THREADS=$(( 2 * $MAX_THREADS ))
+fi
 
 # 1. Change ULib Server (userver_tcp) configuration
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"									  $IROOT/ULib/benchmark.cfg
@@ -11,7 +16,7 @@ sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g"					  $IROOT/ULib/ben
 sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" $IROOT/ULib/benchmark.cfg
 
 # 2. Start ULib Server (userver_tcp)
-export UMEMPOOL="58,0,0,40,273,-15,-14,-20,36"
+export UMEMPOOL="58,0,0,41,273,-15,-14,-20,36"
 
 # Never use setcap inside of TRAVIS 
 [ "$TRAVIS" != "true" ] || { \

+ 29 - 0
frameworks/C++/ulib/setup_mongodb.sh

@@ -0,0 +1,29 @@
+#!/bin/bash
+
+fw_depends ulib
+
+# Travis is broken
+if [ "$TRAVIS" != "true" ]; then
+MAX_THREADS=$(( 3 * $MAX_THREADS / 2 ))
+else
+MAX_THREADS=$(( 2 * $MAX_THREADS ))
+fi
+
+# 1. Change ULib Server (userver_tcp) configuration
+sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"									  $IROOT/ULib/benchmark.cfg
+sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 256|g"								  $IROOT/ULib/benchmark.cfg
+sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g"					  $IROOT/ULib/benchmark.cfg
+sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" $IROOT/ULib/benchmark.cfg
+
+# 2. Start ULib Server (userver_tcp)
+export MONGODB_HOST=$DBHOST
+export UMEMPOOL="1057,0,0,49,274,-14,-15,-24,40"
+
+# Never use setcap inside of TRAVIS 
+[ "$TRAVIS" != "true" ] || { \
+if [ `ulimit -r` -eq 99 ]; then
+	sudo setcap cap_sys_nice,cap_sys_resource,cap_net_bind_service,cap_net_raw+eip $IROOT/ULib/bin/userver_tcp
+fi
+}
+
+$IROOT/ULib/bin/userver_tcp -c $IROOT/ULib/benchmark.cfg &

+ 7 - 2
frameworks/C++/ulib/setup_mysql.sh

@@ -2,7 +2,12 @@
 
 fw_depends ulib
 
-MAX_THREADS=$((2 * $MAX_THREADS))
+# Travis is broken
+if [ "$TRAVIS" != "true" ]; then
+MAX_THREADS=$(( 3 * $MAX_THREADS / 2 ))
+else
+MAX_THREADS=$(( 2 * $MAX_THREADS ))
+fi
 
 # 1. Change ULib Server (userver_tcp) configuration
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET -2|g"								  $IROOT/ULib/benchmark.cfg
@@ -12,7 +17,7 @@ sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" $IROOT
 
 # 2. Start ULib Server (userver_tcp)
 export ORM_DRIVER="mysql"
-export UMEMPOOL="545,0,0,41,275,-14,-13,-25,41"
+export UMEMPOOL="545,0,0,49,275,-14,-13,-25,41"
 export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass character-set=utf8 dbname=hello_world"
 
 # Never use setcap inside of TRAVIS 

+ 7 - 2
frameworks/C++/ulib/setup_plaintext.sh

@@ -2,7 +2,12 @@
 
 fw_depends ulib
 
-MAX_THREADS=$((2 * $MAX_THREADS))
+# Travis is broken
+if [ "$TRAVIS" != "true" ]; then
+MAX_THREADS=$(( 3 * $MAX_THREADS / 2 ))
+else
+MAX_THREADS=$(( 2 * $MAX_THREADS ))
+fi
 
 # 1. Change ULib Server (userver_tcp) configuration
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"										$IROOT/ULib/benchmark.cfg
@@ -11,7 +16,7 @@ sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g"						$IROOT/ULib/benc
 sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 8000|g" $IROOT/ULib/benchmark.cfg
 
 # 2. Start ULib Server (userver_tcp)
-export UMEMPOOL="58,0,0,39,16401,-14,-15,11,25"
+export UMEMPOOL="58,0,0,41,16401,-14,-15,11,25"
 
 # Never use setcap inside of TRAVIS 
 [ "$TRAVIS" != "true" ] || { \

+ 1 - 1
frameworks/C++/ulib/setup_postgres.sh

@@ -2,7 +2,7 @@
 
 fw_depends ulib
 
-MAX_THREADS=$((2 * $MAX_THREADS))
+MAX_THREADS=$(( 2 * $MAX_THREADS ))
 
 # 1. Change ULib Server (userver_tcp) configuration
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET -2|g"								  $IROOT/ULib/benchmark.cfg

+ 7 - 2
frameworks/C++/ulib/setup_redis.sh

@@ -2,7 +2,12 @@
 
 fw_depends ulib
 
-MAX_THREADS=$((2 * $MAX_THREADS))
+# Travis is broken
+if [ "$TRAVIS" != "true" ]; then
+MAX_THREADS=$(( 3 * $MAX_THREADS / 2 ))
+else
+MAX_THREADS=$(( 2 * $MAX_THREADS ))
+fi
 
 # 1. Change ULib Server (userver_tcp) configuration
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"									  $IROOT/ULib/benchmark.cfg
@@ -12,7 +17,7 @@ sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" $IROOT
 
 # 2. Start ULib Server (userver_tcp)
 export REDIS_HOST=$DBHOST
-export UMEMPOOL="1057,0,0,39,274,-14,-15,-24,40"
+export UMEMPOOL="1261,0,0,49,274,-14,-15,-24,40"
 
 # Never use setcap inside of TRAVIS 
 [ "$TRAVIS" != "true" ] || { \

+ 7 - 2
frameworks/C++/ulib/setup_sqlite.sh

@@ -2,7 +2,12 @@
 
 fw_depends ulib
 
-MAX_THREADS=$((2 * $MAX_THREADS))
+# Travis is broken
+if [ "$TRAVIS" != "true" ]; then
+MAX_THREADS=$(( 3 * $MAX_THREADS / 2 ))
+else
+MAX_THREADS=$(( 2 * $MAX_THREADS ))
+fi
 
 # 1. Change ULib Server (userver_tcp) configuration
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"									  $IROOT/ULib/benchmark.cfg
@@ -12,7 +17,7 @@ sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" $IROOT
 
 # 2. Start ULib Server (userver_tcp)
 export ORM_DRIVER="sqlite"
-export UMEMPOOL="545,0,0,41,275,-14,-13,-25,41"
+export UMEMPOOL="545,0,0,49,275,-14,-13,-25,41"
 export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass character-set=utf8 dbname=${IROOT}/ULib/db/%.*s"
 
 # Never use setcap inside of TRAVIS 

+ 4 - 0
frameworks/C++/ulib/source_code

@@ -1,12 +1,16 @@
 ./src/db.usp
 ./src/rdb.usp
+./src/mdb.usp
 ./src/world.h
 ./src/json.usp
 ./src/fortune.h
 ./src/query.usp
 ./src/rquery.usp
+./src/mquery.usp
 ./src/update.usp
 ./src/rupdate.usp
+./src/mupdate.usp
 ./src/fortune.usp
 ./src/rfortune.usp
+./src/mfortune.usp
 ./src/plaintext.usp

+ 1 - 1
frameworks/C++/ulib/src/db.usp

@@ -23,7 +23,7 @@ static void usp_fork_db()
       {
       pstmt_db = U_NEW(UOrmStatement(*psql_db, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
 
-      if (pstmt_db == 0) U_ERROR("usp_fork_db(): we cound't connect to db");
+      if (pstmt_db == 0) U_WARNING("usp_fork_db(): we cound't connect to db");
 
       pworld_db = U_NEW(World);
 

+ 1 - 1
frameworks/C++/ulib/src/fortune.usp

@@ -22,7 +22,7 @@ static void usp_fork_fortune()
       {
       pstmt_fortune = U_NEW(UOrmStatement(*psql_fortune, U_CONSTANT_TO_PARAM("SELECT id, message FROM Fortune")));
 
-      if (pstmt_fortune == 0) U_ERROR("usp_fork_fortune(): we cound't connect to db");
+      if (pstmt_fortune == 0) U_WARNING("usp_fork_fortune(): we cound't connect to db");
 
       if (UOrmDriver::isPGSQL()) *psql_fortune << "BEGIN ISOLATION LEVEL SERIALIZABLE; COMMIT";
 

+ 81 - 0
frameworks/C++/ulib/src/mdb.usp

@@ -0,0 +1,81 @@
+<!--#
+Test type 2: Single database query
+TechEmpower Web Framework Benchmarks
+-->
+<!--#declaration
+#include "world.h"
+
+static World* pworld;
+static UString* jquery;
+static UMongoDBClient* mc;
+
+#ifndef AS_cpoll_cppsp_DO
+static UValue* pvalue;
+#endif
+
+static void usp_fork_mdb()
+{
+   U_TRACE(5, "::usp_fork_mdb()")
+
+   mc = U_NEW(UMongoDBClient);
+
+   if (mc->connect() == false)
+      {
+      U_WARNING("usp_fork_mdb(): connection failed");
+
+      return;
+      }
+
+   if (mc->selectCollection("hello_world", "World") == false)
+      {
+      U_WARNING("usp_fork_mdb(): selectCollection() failed");
+
+      return;
+      }
+
+   pworld = U_NEW(World);
+   jquery = U_NEW(U_STRING_FROM_CONSTANT("{'randomNumber'"));
+
+#ifndef AS_cpoll_cppsp_DO
+   pvalue = U_NEW(UValue(OBJECT_VALUE));
+#endif
+}
+
+#ifdef DEBUG
+static void usp_end_mdb()
+{
+   U_TRACE(5, "::usp_end_mdb()")
+
+   delete mc;
+
+   if (pworld)
+      {
+      delete pworld;
+      delete jquery;
+
+#  ifndef AS_cpoll_cppsp_DO
+      delete pvalue;
+#  endif
+      }
+}
+#endif
+-->
+<!--#header
+Content-Type: application/json
+-->
+<!--#code
+UString result;
+
+(void) mc->findOne(pworld->id = u_get_num_random(10000));
+
+(void) UValue::jread(mc->vitem[0], *jquery, result); // { "_id" : 8980.000000, "id" : 8980.000000, "randomNumber" : 2131.000000 }
+
+pworld->randomNumber = u_strtoul(result.data(), result.end());
+
+#ifdef AS_cpoll_cppsp_DO
+USP_PRINTF_ADD("{\"id\":%u,\"randomNumber\":%v}", pworld->id, result.rep);
+#else
+USP_JSON_stringify(*pvalue, World, *pworld);
+pvalue->clear();
+#endif
+-->

+ 89 - 0
frameworks/C++/ulib/src/mfortune.usp

@@ -0,0 +1,89 @@
+<!--#
+Test type 4: Fortunes
+TechEmpower Web Framework Benchmarks
+-->
+<!--#declaration
+#include "fortune.h"
+
+static UString* jquery;
+static UString* pencoded;
+static UMongoDBClient* mc;
+static Fortune* pfortune2add;
+static UVector<Fortune*>* pvfortune;
+
+static void usp_fork_mfortune()
+{
+   U_TRACE(5, "::usp_fork_mfortune()")
+
+   mc = U_NEW(UMongoDBClient);
+
+   if (mc->connect() == false)
+      {
+      U_WARNING("usp_fork_mfortune(): connection failed");
+
+      return;
+      }
+
+   if (mc->selectCollection("hello_world", "Fortune") == false)
+      {
+      U_WARNING("usp_fork_mfortune(): selectCollection() failed");
+
+      return;
+      }
+
+   jquery       = U_NEW(U_STRING_FROM_CONSTANT("{'message'"));
+   pencoded     = U_NEW(UString(100U));
+   pvfortune    = U_NEW(UVector<Fortune*>);
+   pfortune2add = U_NEW(Fortune(0, U_STRING_FROM_CONSTANT("Additional fortune added at request time.")));
+}
+
+#ifdef DEBUG
+static void usp_end_mfortune()
+{
+   U_TRACE(5, "::usp_end_mfortune()")
+
+   delete mc;
+
+   if (jquery)
+      {
+      delete jquery;
+      delete pencoded;
+      delete pvfortune;
+      delete pfortune2add;
+      }
+}
+#endif
+-->
+<!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><!--#code
+uint32_t i, n;
+UString result;
+
+(void) mc->findAll();
+
+pvfortune->push_back(U_NEW(Fortune(*pfortune2add)));
+
+for (i = 0, n = mc->vitem.size(); i < n; ++i)
+   {
+   (void) UValue::jread(mc->vitem[i], *jquery, result); // { "_id" : 5.000000, "id" : 5.000000, "message" : "A computer program does what you tell it to do, not what you want it to do." }
+
+   pvfortune->push_back(U_NEW(Fortune(i+1, result)));
+   }
+
+pvfortune->sort(Fortune::cmp_obj);
+
+for (i = 0, ++n; i < n; ++i)
+   {
+   Fortune* elem = (*pvfortune)[i];
+
+   UXMLEscape::encode(elem->message, *pencoded);
+
+   USP_PRINTF_ADD(
+      "<tr>"
+      "<td>%u</td>"
+      "<td>%v</td>"
+      "</tr>",
+      elem->id, pencoded->rep);
+   }
+
+pvfortune->clear();
+--></table></body></html>

+ 105 - 0
frameworks/C++/ulib/src/mquery.usp

@@ -0,0 +1,105 @@
+<!--#
+Test type 3: Multiple database queries
+TechEmpower Web Framework Benchmarks
+-->
+<!--#declaration
+#include "world.h"
+
+static UString* jquery;
+static UMongoDBClient* mc;
+static World* pworld_query;
+
+#ifndef AS_cpoll_cppsp_DO
+static UValue* pvalue;
+static UVector<World*>* pvworld_query;
+#endif
+
+static void usp_fork_mquery()
+{
+   U_TRACE(5, "::usp_fork_mquery()")
+
+   mc = U_NEW(UMongoDBClient);
+
+   if (mc->connect() == false)
+      {
+      U_WARNING("usp_fork_mquery(): connection disabled or failed");
+
+      return;
+      }
+
+   if (mc->selectCollection("hello_world", "World") == false)
+      {
+      U_WARNING("usp_fork_mquery(): selectCollection() failed");
+
+      return;
+      }
+
+   jquery       = U_NEW(U_STRING_FROM_CONSTANT("{'randomNumber'"));
+   pworld_query = U_NEW(World);
+
+#ifndef AS_cpoll_cppsp_DO
+   pvalue        = U_NEW(UValue(ARRAY_VALUE));
+   pvworld_query = U_NEW(UVector<World*>(500));
+#endif
+}
+
+#ifdef DEBUG
+static void usp_end_mquery()
+{
+   U_TRACE(5, "::usp_end_mquery()")
+
+   delete mc;
+
+   if (jquery)
+      {
+      delete jquery;
+      delete pworld_query;
+
+#  ifndef AS_cpoll_cppsp_DO
+      delete pvalue;
+      delete pvworld_query;
+#  endif
+      }
+}
+#endif
+-->
+<!--#header
+Content-Type: application/json
+-->
+<!--#code
+UString rnumber;
+int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
+
+#ifdef AS_cpoll_cppsp_DO
+USP_PUTS_CHAR('[');
+#endif
+
+while (true)
+   {
+   (void) mc->findOne(pworld_query->id = u_get_num_random(10000));
+
+   (void) UValue::jread(mc->vitem[0], *jquery, rnumber); // { "_id" : 8980.000000, "id" : 8980.000000, "randomNumber" : 2131.000000 }
+
+#ifdef AS_cpoll_cppsp_DO
+   USP_PRINTF("{\"id\":%u,\"randomNumber\":%v}", pworld_query->id, rnumber.rep);
+#else
+   pworld_query->randomNumber = u_strtoul(rnumber.data(), rnumber.end());
+
+   pvworld_query->push_back(U_NEW(World(*pworld_query)));
+#endif
+
+   if (++i == num_queries) break;
+
+#ifdef AS_cpoll_cppsp_DO
+   USP_PUTS_CHAR(',');
+#endif
+   }
+
+#ifdef AS_cpoll_cppsp_DO
+USP_PUTS_CHAR(']');
+#else
+USP_JSON_stringify(*pvalue, UVector<World*>, *pvworld_query);
+pvalue->clear();
+pvworld_query->clear();
+#endif
+-->

+ 99 - 0
frameworks/C++/ulib/src/mupdate.usp

@@ -0,0 +1,99 @@
+<!--#
+Test type 5: Database updates
+TechEmpower Web Framework Benchmarks
+-->
+<!--#declaration
+#include "world.h"
+
+static UMongoDBClient* mc;
+static World* pworld_update;
+
+#ifndef AS_cpoll_cppsp_DO
+static UValue* pvalue;
+static UVector<World*>* pvworld_update;
+#endif
+
+static void usp_fork_mupdate()
+{
+   U_TRACE(5, "::usp_fork_mupdate()")
+
+   mc = U_NEW(UMongoDBClient);
+
+   if (mc->connect() == false)
+      {
+      U_WARNING("usp_fork_mupdate(): connection disabled or failed");
+
+      return;
+      }
+
+   if (mc->selectCollection("hello_world", "World") == false)
+      {
+      U_WARNING("usp_fork_mupdate(): selectCollection() failed");
+
+      return;
+      }
+
+   pworld_update = U_NEW(World);
+
+#ifndef AS_cpoll_cppsp_DO
+   pvalue         = U_NEW(UValue(ARRAY_VALUE));
+   pvworld_update = U_NEW(UVector<World*>(500));
+#endif
+}
+
+#ifdef DEBUG
+static void usp_end_mupdate()
+{
+   U_TRACE(5, "::usp_end_mupdate()")
+
+   delete mc;
+
+   if (pworld_update)
+      {
+      delete pworld_update;
+
+#  ifndef AS_cpoll_cppsp_DO
+      delete pvalue;
+      delete pvworld_update;
+#  endif
+      }
+}
+#endif
+-->
+<!--#header
+Content-Type: application/json
+-->
+<!--#code
+int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
+
+#ifdef AS_cpoll_cppsp_DO
+USP_PUTS_CHAR('[');
+#endif
+
+while (true)
+   {
+   (void) mc->findOne(pworld_update->id = u_get_num_random(10000));
+
+   (void) mc->update(pworld_update->id, "randomNumber", pworld_update->randomNumber = u_get_num_random(10000));
+
+#ifdef AS_cpoll_cppsp_DO
+   USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", pworld_update->id, pworld_update->randomNumber);
+#else
+   pvworld_update->push_back(U_NEW(World(*pworld_update)));
+#endif
+
+   if (++i == num_queries) break;
+
+#ifdef AS_cpoll_cppsp_DO
+   USP_PUTS_CHAR(',');
+#endif
+   }
+
+#ifdef AS_cpoll_cppsp_DO
+USP_PUTS_CHAR(']');
+#else
+USP_JSON_stringify(*pvalue, UVector<World*>, *pvworld_update);
+pvalue->clear();
+pvworld_update->clear();
+#endif
+-->

+ 15 - 29
frameworks/C++/ulib/src/query.usp

@@ -5,13 +5,13 @@ TechEmpower Web Framework Benchmarks
 <!--#declaration
 #include "world.h"
 
-static World*           pworld_query;
-static UOrmSession*     psql_query;
-static UOrmStatement*   pstmt_query;
-static UVector<World*>* pvworld_query;
+static World*         pworld_query;
+static UOrmSession*   psql_query;
+static UOrmStatement* pstmt_query;
 
 #ifndef AS_cpoll_cppsp_DO
 static UValue* pvalue;
+static UVector<World*>* pvworld_query;
 #endif
 
 static void usp_fork_query()
@@ -24,7 +24,7 @@ static void usp_fork_query()
       {
       pstmt_query = U_NEW(UOrmStatement(*psql_query, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
 
-      if (pstmt_query == 0) U_ERROR("usp_fork_query(): we cound't connect to db");
+      if (pstmt_query == 0) U_WARNING("usp_fork_query(): we cound't connect to db");
 
       if (UOrmDriver::isPGSQL()) *psql_query << "BEGIN TRANSACTION";
 
@@ -33,10 +33,9 @@ static void usp_fork_query()
       pstmt_query->use( pworld_query->id);
       pstmt_query->into(pworld_query->randomNumber);
 
-      pvworld_query = U_NEW(UVector<World*>(500));
-
 #  ifndef AS_cpoll_cppsp_DO
-      pvalue = U_NEW(UValue(ARRAY_VALUE));
+      pvalue        = U_NEW(UValue(ARRAY_VALUE));
+      pvworld_query = U_NEW(UVector<World*>(500));
 #  endif
       }
 }
@@ -48,36 +47,23 @@ static void usp_end_query()
 
    if (pstmt_query)
       {
-      delete   pstmt_query;
-      delete    psql_query;
-      delete pvworld_query;
-      delete  pworld_query;
+      delete pstmt_query;
+      delete psql_query;
+      delete pworld_query;
 
 #  ifndef AS_cpoll_cppsp_DO
       delete pvalue;
+      delete pvworld_query;
 #  endif
       }
 }
 #endif
 -->
-<!--#args
-queries;
--->
 <!--#header
 Content-Type: application/json
 -->
 <!--#code
-int i = 0, num_queries;
-const char* ptr = queries.data();
-
-if (u__isdigit(*ptr) == false) num_queries = 1;
-else
-   {
-   num_queries = u_strtoul(ptr, queries.end());
-
-        if (num_queries <   1) num_queries = 1;
-   else if (num_queries > 500) num_queries = 500;
-   }
+int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 
 #ifdef AS_cpoll_cppsp_DO
 USP_PUTS_CHAR('[');
@@ -91,9 +77,9 @@ while (true)
 
 #ifdef AS_cpoll_cppsp_DO
    USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", pworld_query->id, pworld_query->randomNumber);
-#endif
-
+#else
    pvworld_query->push_back(U_NEW(World(*pworld_query)));
+#endif
 
    if (++i == num_queries) break;
 
@@ -107,6 +93,6 @@ USP_PUTS_CHAR(']');
 #else
 USP_JSON_stringify(*pvalue, UVector<World*>, *pvworld_query);
 pvalue->clear();
-#endif
 pvworld_query->clear();
+#endif
 -->

+ 2 - 3
frameworks/C++/ulib/src/rdb.usp

@@ -30,6 +30,8 @@ static void usp_fork_rdb()
 #ifndef AS_cpoll_cppsp_DO
    pvalue = U_NEW(UValue(OBJECT_VALUE));
 #endif
+
+   u__memcpy(u_buffer, "world:", U_CONSTANT_SIZE("world:"), __PRETTY_FUNCTION__);
 }
 
 #ifdef DEBUG
@@ -56,9 +58,6 @@ Content-Type: application/json
 <!--#code
 UStringRep* rep;
 
-u_put_unalignedp32(u_buffer,   U_MULTICHAR_CONSTANT32('w','o','r','l'));
-u_put_unalignedp16(u_buffer+4, U_MULTICHAR_CONSTANT16('d',':'));
-
 (void) rc->get(u_buffer, 6+u_num2str32(u_buffer+6, pworld->id = u_get_num_random(10000)));
 
 rep = rc->vitem[0].rep;

+ 9 - 22
frameworks/C++/ulib/src/rquery.usp

@@ -6,7 +6,7 @@ TechEmpower Web Framework Benchmarks
 #include "world.h"
 
 static UREDISClient_Base* rc;
-static UVector<World*>* pvworld;
+static UVector<World*>* pvworld_query;
 
 #ifndef AS_cpoll_cppsp_DO
 static UValue* pvalue;
@@ -25,7 +25,7 @@ static void usp_fork_rquery()
       return;
       }
 
-   pvworld = U_NEW(UVector<World*>(500));
+   pvworld_query = U_NEW(UVector<World*>(500));
 
 #ifndef AS_cpoll_cppsp_DO
    pvalue = U_NEW(UValue(ARRAY_VALUE));
@@ -39,9 +39,9 @@ static void usp_end_rquery()
 
    delete rc;
 
-   if (pvworld)
+   if (pvworld_query)
       {
-      delete pvworld;
+      delete pvworld_query;
 
 #  ifndef AS_cpoll_cppsp_DO
       delete pvalue;
@@ -50,27 +50,14 @@ static void usp_end_rquery()
 }
 #endif
 -->
-<!--#args
-queries;
--->
 <!--#header
 Content-Type: application/json
 -->
 <!--#code
 World* pworld;
 UStringRep* rep;
-int i, num_queries;
 char* pbuffer = u_buffer;
-const char* ptr = queries.data();
-
-if (u__isdigit(*ptr) == false) num_queries = 1;
-else
-   {
-   num_queries = u_strtoul(ptr, queries.end());
-
-        if (num_queries <   1) num_queries = 1;
-   else if (num_queries > 500) num_queries = 500;
-   }
+int i, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 
 #ifdef AS_cpoll_cppsp_DO
 USP_PUTS_CHAR('[');
@@ -78,7 +65,7 @@ USP_PUTS_CHAR('[');
 
 for (i = 0; i < num_queries; ++i)
    {
-   pvworld->push_back(pworld = U_NEW(World));
+   pvworld_query->push_back(pworld = U_NEW(World));
 
    u_put_unalignedp64(pbuffer, U_MULTICHAR_CONSTANT64(' ','w','o','r','l','d',':','\0'));
 
@@ -91,7 +78,7 @@ i = 0;
 
 while (true)
    {
-   pworld = pvworld->at(i);
+   pworld = pvworld_query->at(i);
 
    rep = rc->vitem[i].rep;
 
@@ -111,8 +98,8 @@ while (true)
 #ifdef AS_cpoll_cppsp_DO
 USP_PUTS_CHAR(']');
 #else
-USP_JSON_stringify(*pvalue, UVector<World*>, *pvworld);
+USP_JSON_stringify(*pvalue, UVector<World*>, *pvworld_query);
 pvalue->clear();
 #endif
-pvworld->clear();
+pvworld_query->clear();
 -->

+ 1 - 14
frameworks/C++/ulib/src/rupdate.usp

@@ -50,26 +50,13 @@ static void usp_end_rupdate()
 }
 #endif
 -->
-<!--#args
-queries;
--->
 <!--#header
 Content-Type: application/json
 -->
 <!--#code
 World* pworld;
-int i, num_queries;
 char* pbuffer = u_buffer;
-const char* ptr = queries.data();
-
-if (u__isdigit(*ptr) == false) num_queries = 1;
-else
-   {
-   num_queries = u_strtoul(ptr, queries.end());
-
-        if (num_queries <   1) num_queries = 1;
-   else if (num_queries > 500) num_queries = 500;
-   }
+int i, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 
 #ifdef AS_cpoll_cppsp_DO
 USP_PUTS_CHAR('[');

+ 17 - 30
frameworks/C++/ulib/src/update.usp

@@ -5,14 +5,14 @@ TechEmpower Web Framework Benchmarks
 <!--#declaration
 #include "world.h"
 
-static World*           pworld_update;
-static UOrmSession*     psql_update;
-static UOrmStatement*   pstmt1;
-static UOrmStatement*   pstmt2;
-static UVector<World*>* pvworld_update;
+static World*         pworld_update;
+static UOrmSession*   psql_update;
+static UOrmStatement* pstmt1;
+static UOrmStatement* pstmt2;
 
 #ifndef AS_cpoll_cppsp_DO
 static UValue* pvalue;
+static UVector<World*>* pvworld_update;
 #endif
 
 static void usp_fork_update()
@@ -29,19 +29,20 @@ static void usp_fork_update()
       if (pstmt1 == 0 ||
           pstmt2 == 0)
          {
-         U_ERROR("usp_fork_update(): we cound't connect to db");
+         U_WARNING("usp_fork_update(): we cound't connect to db");
          }
 
+		if (UOrmDriver::isPGSQL()) *psql_update << "SET synchronous_commit TO OFF";
+
       pworld_update = U_NEW(World);
 
       pstmt1->use( pworld_update->id);
       pstmt1->into(pworld_update->randomNumber);
       pstmt2->use( pworld_update->randomNumber, pworld_update->id);
 
-      pvworld_update = U_NEW(UVector<World*>(500));
-
 #  ifndef AS_cpoll_cppsp_DO
-      pvalue = U_NEW(UValue(ARRAY_VALUE));
+      pvalue         = U_NEW(UValue(ARRAY_VALUE));
+      pvworld_update = U_NEW(UVector<World*>(500));
 #  endif
       }
 }
@@ -56,36 +57,22 @@ static void usp_end_update()
       {
       delete pstmt1;
       delete pstmt2;
-
-      delete    psql_update;
-      delete pvworld_update;
-      delete  pworld_update;
+      delete psql_update;
+      delete pworld_update;
 
 #  ifndef AS_cpoll_cppsp_DO
       delete pvalue;
+      delete pvworld_update;
 #  endif
       }
 }
 #endif
 -->
-<!--#args
-queries;
--->
 <!--#header
 Content-Type: application/json
 -->
 <!--#code
-int i = 0, num_queries;
-const char* ptr = queries.data();
-
-if (u__isdigit(*ptr) == false) num_queries = 1;
-else
-   {
-   num_queries = u_strtoul(ptr, queries.end());
-
-        if (num_queries <   1) num_queries = 1;
-   else if (num_queries > 500) num_queries = 500;
-   }
+int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 
 #ifdef AS_cpoll_cppsp_DO
 USP_PUTS_CHAR('[');
@@ -103,9 +90,9 @@ while (true)
 
 #ifdef AS_cpoll_cppsp_DO
    USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", pworld_update->id, pworld_update->randomNumber);
-#endif
-
+#else
    pvworld_update->push_back(U_NEW(World(*pworld_update)));
+#endif
 
    if (++i == num_queries) break;
 
@@ -119,6 +106,6 @@ USP_PUTS_CHAR(']');
 #else
 USP_JSON_stringify(*pvalue, UVector<World*>, *pvworld_update);
 pvalue->clear();
-#endif
 pvworld_update->clear();
+#endif
 -->

+ 2 - 0
frameworks/C++/wt/.gitignore

@@ -0,0 +1,2 @@
+/benchmark.wt
+/benchmark_postgres.wt

+ 3 - 1
frameworks/C/duda/.gitignore

@@ -1,3 +1,5 @@
 *.o
 *~
-
+/Makefile
+/main.d
+/ws.duda

+ 1 - 0
frameworks/C/libreactor/benchmark_config.json

@@ -4,6 +4,7 @@
     "default": {
       "setup_file": "setup",
       "plaintext_url": "/plaintext",
+      "json_url": "/json",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Platform",

+ 2 - 0
frameworks/C/libreactor/setup.sh

@@ -2,4 +2,6 @@
 
 fw_depends libreactor
 
+[ "$TRAVIS" == "true" ] || sudo setcap cap_sys_nice,cap_sys_resource+eip $IROOT/libreactor_techempower/rest_server
+
 rest_server &

+ 2 - 0
frameworks/C/onion/.gitignore

@@ -0,0 +1,2 @@
+/assets.h
+/onion

+ 1 - 1
frameworks/CSharp/aspnet/setup_nginx.sh

@@ -1,6 +1,6 @@
 #!/bin/bash
 
-fw_depends nginx mono xsp
+fw_depends nginx mono
 
 sed -i 's|localhost|'"$DBHOST"'|g' src/Web.config
 

+ 1 - 1
frameworks/CSharp/nancy/setup_nginx.sh

@@ -1,6 +1,6 @@
 #!/bin/bash
 
-fw_depends nginx xsp mono
+fw_depends nginx mono
 
 sed -i 's|localhost|'"${DBHOST}"'|g' src/Web.config
 sed -i 's|include /usr/local/nginx/conf/fastcgi_params;|include '"${NGINX_HOME}"'/conf/fastcgi_params;|g' nginx.conf

+ 9 - 0
frameworks/CSharp/revenj/.gitignore

@@ -0,0 +1,9 @@
+*.user
+*.suo
+*.jar
+*.zip
+dsl-compiler.*
+*/bin/*
+*/obj/*
+exe/
+tmp/

+ 29 - 0
frameworks/CSharp/revenj/README.md

@@ -0,0 +1,29 @@
+# Revenj.NET on Mono and Windows
+
+Revenj HTTP server + DB API + JSON API + PostgreSQL.
+It uses precompiled DSL model for POCO classes.
+
+## DSL model
+Data structures are defined in a DSL schema
+
+ * [DSL source](Revenj.Bench/model.dsl)
+
+## Test source
+
+ * [C#](Revenj.Bench/RestService.cs)
+
+## Test URLs
+
+ * Plaintext - `http://localhost:8080/bench/plaintext`
+ * JSON - `http://localhost:8080/bench/json`
+ * DB - `http://localhost:8080/bench/db`
+ * Queries - `http://localhost:8080/bench/queries/{count}`
+ * Updates -  `http://localhost:8080/bench/updates/{count}`
+
+## Software Versions
+The tests were run with:
+
+ * [Mono 4.2](http://www.mono-project.com/)
+ * [.NET 4.0](https://www.microsoft.com/net)
+ * [Postgres 9.3](http://www.postgresql.org/)
+ * [Revenj.NET 1.2.1](http://github.com/ngs-doo/revenj)

+ 29 - 0
frameworks/CSharp/revenj/Revenj.Bench.sln

@@ -0,0 +1,29 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Revenj.Bench", "Revenj.Bench\Revenj.Bench.csproj", "{14DC9873-30EA-41DA-8D7B-5AA03E7E2EE2}"
+EndProject
+Global
+	GlobalSection(DslPlatformSolutionProperties) = preSolution
+		Php.Name = Php
+		Php.Target = Php
+		Postgres.Compile = True
+		Postgres.Name = ServerModel
+		Postgres.Target = exe
+		Postgres.Dependencies = exe
+		Postgres.WithManualJson = True
+	EndGlobalSection
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{14DC9873-30EA-41DA-8D7B-5AA03E7E2EE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{14DC9873-30EA-41DA-8D7B-5AA03E7E2EE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{14DC9873-30EA-41DA-8D7B-5AA03E7E2EE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{14DC9873-30EA-41DA-8D7B-5AA03E7E2EE2}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 32 - 0
frameworks/CSharp/revenj/Revenj.Bench/Context.cs

@@ -0,0 +1,32 @@
+using System;
+using System.IO;
+using FrameworkBench;
+using Revenj.DatabasePersistence;
+using Revenj.DatabasePersistence.Postgres;
+using Revenj.DomainPatterns;
+using Revenj.Extensibility;
+using Revenj.Utility;
+
+namespace Revenj.Bench
+{
+	internal class Context
+	{
+		public readonly ChunkedMemoryStream Stream;
+		public readonly TextWriter Writer;
+		public readonly IPersistableRepository<World> Repository;
+		public readonly IRepositoryBulkReader BulkReader;
+		public readonly Lazy<World>[] LazyWorlds = new Lazy<World>[512];
+		public readonly World[] Worlds = new World[512];
+
+		public Context(IServiceProvider service)
+		{
+			Stream = ChunkedMemoryStream.Static();
+			Writer = Stream.GetWriter();
+			var dqm = service.Resolve<IDatabaseQueryManager>();
+			var factory = service.Resolve<IObjectFactory>().CreateInnerFactory();
+			factory.RegisterInterfaces(dqm.StartQuery(false));
+			Repository = factory.Resolve<IPersistableRepository<World>>();
+			BulkReader = factory.BulkRead(ChunkedMemoryStream.Static());
+		}
+	}
+}

+ 154 - 0
frameworks/CSharp/revenj/Revenj.Bench/RestService.cs

@@ -0,0 +1,154 @@
+using System;
+using System.ComponentModel;
+using System.IO;
+using System.ServiceModel;
+using System.ServiceModel.Web;
+using System.Text;
+using FrameworkBench;
+using Revenj.Api;
+using Revenj.DomainPatterns;
+using Revenj.Serialization;
+using Revenj.Utility;
+
+namespace Revenj.Bench
+{
+	[ServiceContract(Namespace = "https://github.com/ngs-doo/revenj")]
+	public interface IRestService
+	{
+		[OperationContract]
+		[WebGet(UriTemplate = "/plaintext")]
+		[Description("Plain text response")]
+		Stream PlainText();
+
+		[OperationContract]
+		[WebGet(UriTemplate = "/json")]
+		[Description("JSON response")]
+		Stream JSON();
+
+		[OperationContract]
+		[WebGet(UriTemplate = "/db")]
+		[Description("Single database query")]
+		Stream SingleQuery();
+
+		[OperationContract]
+		[WebGet(UriTemplate = "/queries/{count}")]
+		[Description("Multiple database queries")]
+		Stream MultipleQueries(string count);
+
+		[OperationContract]
+		[WebGet(UriTemplate = "/updates/{count}")]
+		[Description("Database updates")]
+		Stream Updates(string count);
+	}
+
+	public class RestService : IRestService
+	{
+		private static readonly ChunkedMemoryStream HelloWorld = ChunkedMemoryStream.Static();
+		private static readonly string[] IDs = new string[10001];
+		[ThreadStatic]
+		private static Context Context;
+		private static Context GetContext(IServiceProvider services)
+		{
+			if (Context == null)
+				Context = new Context(services);
+			Context.Stream.Reset();
+			return Context;
+		}
+
+		static RestService()
+		{
+			var hwText = Encoding.UTF8.GetBytes("Hello, World!");
+			HelloWorld.Write(hwText, 0, hwText.Length);
+			HelloWorld.Position = 0;
+			for (int i = 0; i < IDs.Length; i++)
+				IDs[i] = i.ToString();
+		}
+
+		private Random Random = new Random(0);
+		private readonly IServiceProvider Services;
+
+		public RestService(IServiceProvider services)
+		{
+			this.Services = services;
+		}
+
+		public Stream PlainText()
+		{
+			ThreadContext.Response.ContentType = "text/plain";
+			return HelloWorld;
+		}
+
+		private Stream ReturnJSON(IJsonObject value, ChunkedMemoryStream cms)
+		{
+			value.Serialize(cms);
+			ThreadContext.Response.ContentType = "application/json";
+			return cms;
+		}
+
+		public Stream JSON()
+		{
+			var ctx = GetContext(Services);
+			return ReturnJSON(new Message { message = "Hello, World!" }, ctx.Stream);
+		}
+
+		public Stream SingleQuery()
+		{
+			var id = Random.Next(10000) + 1;
+			var ctx = GetContext(Services);
+			var world = ctx.Repository.Find(IDs[id]);
+			return ReturnJSON(world, ctx.Stream);
+		}
+
+		private void LoadWorlds(int repeat, Context ctx)
+		{
+			var reader = ctx.BulkReader;
+			var lazyResult = ctx.LazyWorlds;
+			var worlds = ctx.Worlds;
+			reader.Reset(true);
+			for (int i = 0; i < repeat; i++)
+			{
+				var id = Random.Next(10000) + 1;
+				lazyResult[i] = reader.Find<World>(IDs[id]);
+			}
+			reader.Execute();
+			for (int i = 0; i < repeat; i++)
+				worlds[i] = lazyResult[i].Value;
+		}
+
+		public Stream MultipleQueries(string count)
+		{
+			int repeat;
+			int.TryParse(count, out repeat);
+			if (repeat < 1) repeat = 1;
+			else if (repeat > 500) repeat = 500;
+			var ctx = GetContext(Services);
+			LoadWorlds(repeat, ctx);
+			var cms = ctx.Stream;
+			ctx.Worlds.Serialize(cms, repeat);
+			ThreadContext.Response.ContentType = "application/json";
+			return cms;
+		}
+
+		private static readonly Comparison<World> ASC = (l, r) => l.id - r.id;
+
+		public Stream Updates(string count)
+		{
+			int repeat;
+			int.TryParse(count, out repeat);
+			if (repeat < 1) repeat = 1;
+			else if (repeat > 500) repeat = 500;
+			var ctx = GetContext(Services);
+			LoadWorlds(repeat, ctx);
+			var result = new World[repeat];
+			Array.Copy(ctx.Worlds, result, repeat);
+			for (int i = 0; i < result.Length; i++)
+				result[i].randomNumber = Random.Next(10000) + 1;
+			Array.Sort(result, ASC);
+			ctx.Repository.Update(result);
+			var cms = ctx.Stream;
+			result.Serialize(cms);
+			ThreadContext.Response.ContentType = "application/json";
+			return cms;
+		}
+	}
+}

+ 101 - 0
frameworks/CSharp/revenj/Revenj.Bench/Revenj.Bench.csproj

@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{14DC9873-30EA-41DA-8D7B-5AA03E7E2EE2}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Revenj.Bench</RootNamespace>
+    <AssemblyName>Revenj.Bench</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\exe\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\exe\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Revenj.Api.Interface">
+      <HintPath>..\exe\Revenj.Api.Interface.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Revenj.DatabasePersistence.Interface">
+      <HintPath>..\exe\Revenj.DatabasePersistence.Interface.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Revenj.DatabasePersistence.Postgres">
+      <HintPath>..\exe\Revenj.DatabasePersistence.Postgres.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Revenj.DomainPatterns.Interface">
+      <HintPath>..\exe\Revenj.DomainPatterns.Interface.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Revenj.Extensibility.Interface">
+      <HintPath>..\exe\Revenj.Extensibility.Interface.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Revenj.Processing">
+      <HintPath>..\exe\Revenj.Processing.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Revenj.Serialization">
+      <HintPath>..\exe\Revenj.Serialization.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Revenj.Serialization.Interface">
+      <HintPath>..\exe\Revenj.Serialization.Interface.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Revenj.Utility">
+      <HintPath>..\exe\Revenj.Utility.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="ServerModel">
+      <HintPath>..\exe\ServerModel.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.ServiceModel" />
+    <Reference Include="System.ServiceModel.Web" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Context.cs" />
+    <Compile Include="RestService.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\Revenj.Http.exe.config">
+      <Link>Revenj.Http.exe.config</Link>
+      <SubType>Designer</SubType>
+    </None>
+    <None Include="model.dsl" />
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Properties\" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 9 - 0
frameworks/CSharp/revenj/Revenj.Bench/model.dsl

@@ -0,0 +1,9 @@
+module FrameworkBench {
+	struct Message {
+		String message;
+	}
+	sql World from world(id) {
+		int id;
+		int randomNumber from randomnumber;
+	}
+}

+ 30 - 0
frameworks/CSharp/revenj/Revenj.Http.exe.config

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+  <configSections>
+    <section name="autofacConfiguration" type="Revenj.Extensibility.Autofac.Configuration.SectionHandler, Revenj.Extensibility" />
+  </configSections>
+  <appSettings>
+    <add key="PluginsPath" value="." />
+    <add key="ServerAssembly" value="ServerModel.dll"/>
+    <add key="ConnectionString" value="server=localhost;port=5432;database=hello_world;user=benchmarkdbuser;password=benchmarkdbpass" />
+    <add key="HttpAddress_local" value="http://0.0.0.0:8080/" />
+    <add key="Revenj.HttpServer" value="Socket"/>
+    <add key="CustomAuth" value="Revenj.Http.NoAuth"/>
+    <add key="Revenj.Notifications" value="disabled"/>
+  </appSettings>
+  <system.serviceModel>
+    <serviceHostingEnvironment>
+      <serviceActivations>
+        <add relativeAddress="bench" service="Revenj.Bench.RestService, Revenj.Bench" />
+      </serviceActivations>
+    </serviceHostingEnvironment>
+  </system.serviceModel>
+  <autofacConfiguration>
+    <modules>
+      <module type="Revenj.Wcf.StandardModule, Revenj.Wcf" />
+    </modules>
+    <components>
+      <component type="Revenj.Http.NoAuth, Revenj.Http" service="Revenj.Security.IPermissionManager, Revenj.Security.Interface" />
+    </components>
+  </autofacConfiguration>
+</configuration>

+ 49 - 0
frameworks/CSharp/revenj/benchmark_config.json

@@ -0,0 +1,49 @@
+{
+  "framework": "Revenj.NET",
+  "tests": [{
+    "windows": {
+      "setup_file": "setup",
+      "json_url": "/bench/json",
+      "db_url": "/bench/db",
+      "query_url": "/bench/queries/",
+      "plaintext_url": "/bench/plaintext",
+      "update_url": "/bench/updates/",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Platform",
+      "database": "Postgres",
+      "database_os": "Linux",
+      "framework": "Revenj.NET",
+      "language": "C#",
+      "orm": "Full",
+      "platform": ".NET",
+      "webserver": "Revenj.NET",
+      "os": "Windows",
+      "display_name": "Revenj.NET",
+      "notes": "",
+      "versus": ""
+    },
+    "default": {
+      "setup_file": "setup",
+      "json_url": "/bench/json",
+      "db_url": "/bench/db",
+      "query_url": "/bench/queries/",
+      "plaintext_url": "/bench/plaintext",
+      "update_url": "/bench/updates/",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Platform",
+      "database": "Postgres",
+      "database_os": "Linux",
+      "framework": "Revenj.NET",
+      "language": "C#",
+      "orm": "Full",
+      "platform": "Mono",
+      "webserver": "Revenj.NET",
+      "os": "Linux",
+      "display_name": "Revenj.NET",
+      "notes": "",
+      "versus": ""
+    }
+  }]
+}

+ 3 - 0
frameworks/CSharp/revenj/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends mono java

+ 75 - 0
frameworks/CSharp/revenj/setup.ps1

@@ -0,0 +1,75 @@
+param($action)
+
+if (!$TROOT) {
+  $TROOT = "C:\FrameworkBenchmarks\frameworks\CSharp\revenj"
+}
+if (!$DBHOST) {
+  $DBHOST = "localhost"
+}
+
+Add-Type -AssemblyName System.IO.Compression.FileSystem
+
+$msbuild = $Env:windir + "\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe"
+$java=$Env:JAVA_HOME + "\bin\java"
+$dslclc=$TROOT + "\dsl-clc.jar"
+$httpZip=$TROOT + "\http-server.zip"
+$dslZip=$TROOT + "\dsl-compiler.zip"
+$sln=$TROOT + "\Revenj.Bench.sln"
+$revenj=$TROOT + "\exe\Revenj.Http.exe"
+$exe=$TROOT + "\exe\"
+$config=$TROOT + "\exe\Revenj.Http.exe.config"
+
+echo "Stopping existing Revenj.Http"
+Stop-Process -Name "Revenj.Http*" -ErrorAction 'SilentlyContinue' | Out-Null
+
+if ($action -eq 'start') {
+
+	echo "Cleaning up..."
+	If (Test-Path $TROOT/exe) {
+	  rmdir $TROOT/exe -recurse -force
+	}
+	if (Test-Path $TROOT/dsl-clc.jar) {
+	  rm $TROOT/dsl-clc.jar
+	}
+	if (Test-Path $TROOT/http-server.zip) {
+	  rm $TROOT/http-server.zip
+	}
+	if (Test-Path $TROOT/dsl-compiler.zip) {
+	  rm $TROOT/dsl-compiler.zip
+	}
+	if (Test-Path $TROOT/dsl-compiler.exe) {
+	  rm $TROOT/dsl-compiler.exe
+	}
+
+	echo "Download DSL compiler client"
+	$client = new-object System.Net.WebClient
+	$client.DownloadFile( "https://github.com/ngs-doo/dsl-compiler-client/releases/download/1.5.0/dsl-clc.jar", $dslclc )
+
+	echo "Download Revenj HTTP server"
+	$client = new-object System.Net.WebClient
+	$client.DownloadFile( "https://github.com/ngs-doo/revenj/releases/download/1.2.1/http-server.zip", $httpZip )
+
+	echo "Unzipping HTTP server"
+	[System.IO.Compression.ZipFile]::ExtractToDirectory($httpZip, $exe)
+
+	echo "Download DSL compiler for Revenj.NET 1.2.1"
+	$client = new-object System.Net.WebClient
+	$client.DownloadFile( "https://github.com/ngs-doo/revenj/releases/download/1.2.1/dsl-compiler.zip", $dslZip )
+
+	echo "Unzipping DSL compiler"
+	[System.IO.Compression.ZipFile]::ExtractToDirectory($dslZip, $TROOT)
+	
+	echo "Compiling the server model and downloading DSL Platform compiler..."
+	&$java -jar $dslclc temp=$TROOT/tmp/ force dsl=$TROOT/Revenj.Bench manual-json revenj.net=$TROOT/exe/ServerModel.dll no-prompt dependencies:revenj.net=$TROOT/exe download compiler=$TROOT/dsl-compiler.exe
+
+	echo "Compiling the benchmark project..."
+	&$msbuild $sln /p:Configuration=Release /t:Rebuild
+
+	echo "Copying the configuration template"
+	$template = Get-Content $TROOT/Revenj.Http.exe.config
+	$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
+	[System.IO.File]::WriteAllText($config, $template.Replace("server=localhost", "server=" + $DBHOST), $Utf8NoBomEncoding)
+
+	echo "Starting Revenj..."
+	Start-Process $revenj
+}

+ 43 - 0
frameworks/CSharp/revenj/setup.sh

@@ -0,0 +1,43 @@
+#!/bin/bash
+
+fw_depends java mono
+
+echo "Cleaning up..."
+rm -rf $TROOT/exe $TROOT/tmp $TROOT/dsl-clc.jar $TROOT/http-server.zip  $TROOT/dsl-compiler.zip $TROOT/dsl-compiler.exe
+
+echo "Download DSL compiler client"
+wget -O $TROOT/dsl-clc.jar https://github.com/ngs-doo/dsl-compiler-client/releases/download/1.5.0/dsl-clc.jar
+
+echo "Download Revenj.NET HTTP server 1.2.1"
+wget -O $TROOT/http-server.zip https://github.com/ngs-doo/revenj/releases/download/1.2.1/http-server.zip
+
+echo "Unzipping HTTP server"
+unzip $TROOT/http-server.zip -d $TROOT/exe
+
+echo "Download DSL compiler for Revenj.NET 1.2.1"
+wget -O $TROOT/dsl-compiler.zip https://github.com/ngs-doo/revenj/releases/download/1.2.1/dsl-compiler.zip
+
+echo "Unzipping DSL compiler"
+unzip $TROOT/dsl-compiler.zip -d $TROOT
+
+echo "Compiling the server model and downloading dependencies..."
+java -jar $TROOT/dsl-clc.jar \
+	temp=$TROOT/tmp/ \
+	force \
+	dsl=$TROOT/Revenj.Bench \
+	manual-json \
+	compiler=$TROOT/dsl-compiler.exe \
+	revenj.net=$TROOT/exe/ServerModel.dll \
+	no-prompt \
+	dependencies:revenj.net=$TROOT/exe \
+	download
+
+echo "Compiling the benchmark project..."
+xbuild $TROOT/Revenj.Bench/Revenj.Bench.csproj /t:Rebuild /p:Configuration=Release
+
+echo "Copying the configuration template"
+cat $TROOT/Revenj.Http.exe.config | sed 's|\(ConnectionString.*server=\)localhost|\1'"${DBHOST}"'|' > $TROOT/exe/Revenj.Http.exe.config
+
+echo "Running the Revenj instance"
+mono $TROOT/exe/Revenj.Http.exe
+sleep 5

+ 4 - 0
frameworks/CSharp/revenj/source_code

@@ -0,0 +1,4 @@
+./revenj/Revenj.Bench/Context.cs
+./revenj/Revenj.Bench/RestService.cs
+./revenj/Revenj.Bench/model.dsl
+./revenj/Revenj.Http.exe.config

+ 1 - 1
frameworks/CSharp/servicestack/setup_nginx.sh

@@ -1,6 +1,6 @@
 #!/bin/bash
 
-fw_depends nginx xsp mono
+fw_depends nginx mono
 
 sed -i 's|localhost|'"$DBHOST"'|g' src/Web.config
 sed -i 's|/usr/local/nginx/|'"${IROOT}"'/nginx/|g' nginx.conf

+ 1 - 1
frameworks/CSharp/servicestack/setup_xsp.sh

@@ -1,6 +1,6 @@
 #!/bin/bash
 
-fw_depends nginx xsp mono
+fw_depends nginx mono
 
 sed -i 's|localhost|'"$DBHOST"'|g' src/Web.config
 # extra cleaning

+ 4 - 4
frameworks/Clojure/aleph/README.md

@@ -1,6 +1,6 @@
 # Compojure Benchmarking Test
 
-This is the [Aleph](https;//github.com/ztellman/aleph) portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
+This is the [Aleph](https://github.com/ztellman/aleph) portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
 
 ### JSON Encoding Test
 
@@ -10,9 +10,9 @@ This is the [Aleph](https;//github.com/ztellman/aleph) portion of a [benchmarkin
 The dependencies are documented in [project.clj](hello/project.clj),
 but the main ones are:
 
-* [Aleph 0.4.0](https://github.com/ztellman/aleph)
-* [Clojure 1.7.0-beta2](http://clojure.org/)
-* [Cheshire 5.4.0](https://github.com/dakrone/cheshire), which in turn uses [Jackson](http://jackson.codehaus.org/)
+* [Aleph 0.4.1-beta2](https://github.com/ztellman/aleph)
+* [Clojure 1.8.0](http://clojure.org/)
+* [Cheshire 5.5.0](https://github.com/dakrone/cheshire), which in turn uses [Jackson](http://jackson.codehaus.org/)
 
 ## Test URLs
 ### JSON Encoding Test

+ 5 - 5
frameworks/Clojure/aleph/hello/project.clj

@@ -1,9 +1,9 @@
 (defproject hello "aleph"
   :description "JSON/plaintext tests"
-  :dependencies [[org.clojure/clojure "1.7.0-beta2"]
-                 [clj-tuple "0.2.1"]
-                 [org.clojure/tools.cli "0.3.1"]
-                 [aleph "0.4.0"]
-                 [cheshire "5.4.0"]]
+  :dependencies [[org.clojure/clojure "1.8.0"]
+                 [clj-tuple "0.2.2"]
+                 [org.clojure/tools.cli "0.3.3"]
+                 [aleph "0.4.1-beta2"]
+                 [cheshire "5.5.0"]]
   :main hello.handler
   :aot :all)

+ 1 - 1
frameworks/Clojure/aleph/setup.sh

@@ -1,6 +1,6 @@
 #!/bin/bash
 
-fw_depends java7 leiningen
+fw_depends java leiningen
 
 cd hello
 lein clean

+ 1 - 1
frameworks/Clojure/compojure/README.md

@@ -14,7 +14,7 @@ This is the Compojure portion of a [benchmarking test suite](../) comparing a va
 The dependencies are documented in [project.clj](hello/project.clj),
 but the main ones are:
 
-* [Clojure 1.7.0](http://clojure.org/)
+* [Clojure 1.8.0](http://clojure.org/)
 * [Compojure 1.4.0](https://github.com/weavejester/compojure)
 * [Ring-JSON 0.4.0](https://github.com/ring-clojure/ring-json), which in turn uses [Cheshire](https://github.com/dakrone/cheshire), which in turn uses [Jackson](http://jackson.codehaus.org/)
 * [Korma 0.4.2](http://sqlkorma.com/)

+ 2 - 2
frameworks/Clojure/compojure/hello/project.clj

@@ -2,14 +2,14 @@
   :description "FrameworkBenchmarks test implementations"
   :url "http://localhost:3000/"
   :min-lein-version "2.0.0"
-  :dependencies [[org.clojure/clojure "1.7.0"]
+  :dependencies [[org.clojure/clojure "1.8.0"]
                  [compojure "1.4.0"]
                  [ring/ring-json "0.4.0"]
                  [korma "0.4.2"]
                  [log4j "1.2.15" :exclusions [javax.mail/mail javax.jms/jms com.sun.jdmk/jmxtools com.sun.jmx/jmxri]]
                  [mysql/mysql-connector-java "5.1.38"]
                  [org.clojure/java.jdbc "0.3.7"]
-                 [c3p0/c3p0 "0.9.1.2"]
+                 [hikari-cp "1.5.0"]
                  [hiccup "1.0.5"]]
   :plugins [[lein-ring "0.9.7"]]
   :ring {:handler hello.handler/app}

+ 55 - 50
frameworks/Clojure/compojure/hello/src/hello/handler.clj

@@ -1,5 +1,4 @@
 (ns hello.handler
-  (:import com.mchange.v2.c3p0.ComboPooledDataSource)
   (:use compojure.core
         ring.middleware.content-type
         ring.middleware.json
@@ -11,7 +10,8 @@
   (:require [compojure.handler :as handler]
             [compojure.route :as route]
             [ring.util.response :as ring-resp]
-            [clojure.java.jdbc :as jdbc]))
+            [clojure.java.jdbc :as jdbc]
+            [hikari-cp.core :refer :all]))
 
 (defn sanitize-queries-param
   "Sanitizes the `queries` parameter. Clamps the value between 1 and 500.
@@ -36,31 +36,30 @@
           :delimiters "" ;; remove delimiters
           :maximum-pool-size 256}))
 
-;; MySQL database connection for java.jdbc "raw"
-;; https://github.com/clojure/java.jdbc/blob/master/doc/clojure/java/jdbc/ConnectionPooling.md
-(def db-spec-mysql-raw
-  {:classname "com.mysql.jdbc.Driver"
-   :subprotocol "mysql"
-   :subname "//127.0.0.1:3306/hello_world?jdbcCompliantTruncation=false&elideSetAutoCommits=true&useLocalSessionState=true&cachePrepStmts=true&cacheCallableStmts=true&alwaysSendSetIsolation=false&prepStmtCacheSize=4096&cacheServerConfiguration=true&prepStmtCacheSqlLimit=2048&zeroDateTimeBehavior=convertToNull&traceProtocol=false&useUnbufferedInput=false&useReadAheadInput=false&maintainTimeStats=false&useServerPrepStmts&cacheRSMetadata=true"
-   :user "benchmarkdbuser"
-   :password "benchmarkdbpass"})
+;; MySQL database connection for java.jdbc "raw" using HikariCP
+(def datasource-options-hikaricp {:auto-commit        true
+                                  :read-only          false
+                                  :connection-timeout 30000
+                                  :validation-timeout 5000
+                                  :idle-timeout       600000
+                                  :max-lifetime       1800000
+                                  :minimum-idle       10
+                                  :maximum-pool-size  256
+                                  :pool-name          "db-pool"
+                                  :adapter            "mysql"
+                                  :username           "benchmarkdbuser"
+                                  :password           "benchmarkdbpass"
+                                  :database-name      "hello_world"
+                                  :server-name        "127.0.0.1"
+                                  :port-number        3306
+                                  :register-mbeans    false})
 
-(defn pool
-  [spec]
-  (let [cpds (doto (ComboPooledDataSource.)
-               (.setDriverClass (:classname spec))
-               (.setJdbcUrl (str "jdbc:" (:subprotocol spec) ":" (:subname spec)))
-               (.setUser (:user spec))
-               (.setPassword (:password spec))
-               ;; expire excess connections after 30 minutes of inactivity:
-               (.setMaxIdleTimeExcessConnections (* 30 60))
-               ;; expire connections after 3 hours of inactivity:
-               (.setMaxIdleTime (* 3 60 60)))]
-    {:datasource cpds}))
+;; Create HikariCP-pooled "raw" jdbc data source
+(def db-spec-mysql-raw-hikaricp
+  (make-datasource datasource-options-hikaricp))
 
-(def pooled-db (delay (pool db-spec-mysql-raw)))
-
-(defn db-mysql-raw [] @pooled-db)
+;; Get a HikariCP-pooled "raw" jdbc connection
+(defn db-mysql-raw [] {:datasource db-spec-mysql-raw-hikaricp})
 
 ;; Set up entity World and the database representation
 (defentity world
@@ -144,30 +143,33 @@
   "Using Korma: Changes the :randomNumber of a number of world entities.
   Persists the changes to sql then returns the updated entities"
   [queries]
-(let [results (run-queries queries)]
-    (for [w results]
-      (update-in w [:randomNumber (inc (rand-int 9999))]
-        (update world
-                (set-fields {:randomNumber (:randomNumber w)})
-                (where {:id [:id w]}))))
+  (let [results (map #(assoc % :randomNumber (inc (rand-int 9999))) (run-queries queries))]
+    (doseq [{:keys [id randomNumber]} results]
+      (update world
+              (set-fields {:randomNumber randomNumber})
+              (where {:id id})))
     results))
 
 (defn update-and-persist-raw
   "Using JDBC: Changes the :randomNumber of a number of world entities.
   Persists the changes to sql then returns the updated entities"
   [queries]
-(let [results (run-queries queries)]
-    (for [w results]
-      (update-in w [:randomNumber (inc (rand-int 9999))]
-        (jdbc/update! (db-mysql-raw) :world {:randomNumber (:randomNumber w)} ["id = ?" (:id w)])))
-    results))
+  (let [world (map #(assoc % :randomnumber (inc (rand-int 9999))) (run-queries-raw queries))]
+    (doseq [{:keys [id randomnumber]} world]
+      (jdbc/update!
+       (db-mysql-raw)
+       :world {:randomnumber randomnumber}
+       ["id = ?" id]))
+    world))
 
-(def json-serialization
+(defn json-serialization
   "Test 1: JSON serialization"
+  []
   (ring-resp/response {:message "Hello, World!"}))
 
-(def single-query-test
+(defn single-query-test
   "Test 2: Single database query"
+  []
   (ring-resp/response (first (run-queries 1))))
 
 (defn multiple-queries-test
@@ -178,8 +180,9 @@
       (run-queries)
       (ring-resp/response)))
 
-(def single-query-test-raw
+(defn single-query-test-raw
   "Test 2: Single database query (raw)"
+  []
   (-> 1
       (run-queries-raw)
       (first)
@@ -193,8 +196,9 @@
       (run-queries-raw)
       (ring-resp/response)))
 
-(def fortune-test
+(defn fortune-test
   "Test 4: Fortunes"
+  []
   (->
     (get-fortunes get-all-fortunes-korma)
     (fortunes-hiccup)
@@ -202,8 +206,9 @@
     (ring-resp/content-type "text/html")
     (ring-resp/charset "utf-8")))
 
-(def fortune-test-raw
+(defn fortune-test-raw
   "Test 4: Fortunes Raw"
+  []
   (->
     (get-fortunes get-all-fortunes-raw)
     (fortunes-hiccup)
@@ -237,19 +242,19 @@
 (defroutes app-routes
   (GET "/"                     [] "Hello, World!")
   (GET "/plaintext"            [] plaintext)
-  (GET "/json"                 [] json-serialization)
-  (GET "/db"                   [] single-query-test)
+  (GET "/json"                 [] (json-serialization))
+  (GET "/db"                   [] (single-query-test))
   (GET "/queries/:queries"     [queries] (multiple-queries-test queries))
-  (GET "/queries/"             [] (multiple-queries-test queries)) ; When param is omitted
-  (GET "/fortunes"             [] fortune-test)
+  (GET "/queries/"             [] (multiple-queries-test 1)) ; When param is omitted
+  (GET "/fortunes"             [] (fortune-test))
   (GET "/updates/:queries"     [queries] (db-updates queries))
-  (GET "/updates/"             [] (db-updates queries)) ; When param is omitted
-  (GET "/raw/db"               [] single-query-test-raw)
+  (GET "/updates/"             [] (db-updates 1)) ; When param is omitted
+  (GET "/raw/db"               [] (single-query-test-raw))
   (GET "/raw/queries/:queries" [queries] (multiple-queries-test-raw queries))
-  (GET "/raw/queries/"         [] (multiple-queries-test-raw queries)) ; When param is omitted
-  (GET "/raw/fortunes"         [] fortune-test-raw)
+  (GET "/raw/queries/"         [] (multiple-queries-test-raw 1)) ; When param is omitted
+  (GET "/raw/fortunes"         [] (fortune-test-raw))
   (GET "/raw/updates/:queries" [queries] (db-updates-raw queries))
-  (GET "/raw/updates/"         [] (db-updates-raw queries)) ; When param is omitted
+  (GET "/raw/updates/"         [] (db-updates-raw 1)) ; When param is omitted
   (route/not-found "Not Found"))
 
 (def app

+ 2 - 2
frameworks/Clojure/compojure/setup.sh

@@ -1,8 +1,8 @@
 #!/bin/bash
 
-fw_depends java8 resin leiningen
+fw_depends java resin leiningen
 
-sed -i 's|:subname "//.*:3306|:subname "//'"${DBHOST}"':3306|g' hello/src/hello/handler.clj
+sed -i 's|127.0.0.1|'"${DBHOST}"'|g' hello/src/hello/handler.clj
 
 cd hello
 lein clean

+ 1 - 1
frameworks/Clojure/http-kit/README.md

@@ -14,7 +14,7 @@ This is the Compojure (using http-kit) portion of a [benchmarking test suite](..
 The dependencies are documented in [project.clj](hello/project.clj),
 but the main ones are:
 
-* [Clojure 1.7.0](http://clojure.org/)
+* [Clojure 1.8.0](http://clojure.org/)
 * [http-kit](http://http-kit.org)
 * [Ring-JSON 0.4.0](https://github.com/ring-clojure/ring-json), which in turn uses [Cheshire](https://github.com/dakrone/cheshire), which in turn uses [Jackson](http://jackson.codehaus.org/)
 * [Korma 0.4.2](http://sqlkorma.com/)

+ 2 - 2
frameworks/Clojure/http-kit/hello/project.clj

@@ -1,7 +1,7 @@
 (defproject hello "http-kit"
   :description "FrameworkBenchmarks test implementations"
   :url "http://localhost:8080/"
-  :dependencies [[org.clojure/clojure "1.7.0"]
+  :dependencies [[org.clojure/clojure "1.8.0"]
                  [compojure "1.4.0"]
                  [ring/ring-json "0.4.0"]
                  [org.clojure/tools.cli "0.2.1"]
@@ -15,7 +15,7 @@
                  [ring/ring-jetty-adapter "1.4.0"]
                  [mysql/mysql-connector-java "5.1.38"]
                  [org.clojure/java.jdbc "0.3.7"]
-                 [c3p0/c3p0 "0.9.1.2"]
+                 [hikari-cp "1.5.0"]
                  [hiccup "1.0.5"]]
   :plugins [[lein-ring "0.9.7"]]
   :ring {:handler hello.handler/app}

+ 57 - 52
frameworks/Clojure/http-kit/hello/src/hello/handler.clj

@@ -1,6 +1,5 @@
 (ns hello.handler
   (:gen-class)
-  (:import com.mchange.v2.c3p0.ComboPooledDataSource)
   (:use compojure.core
         ring.middleware.json
         org.httpkit.server
@@ -13,7 +12,8 @@
   (:require [compojure.handler :as handler]
             [compojure.route :as route]
             [ring.util.response :as ring-resp]
-            [clojure.java.jdbc :as jdbc]))
+            [clojure.java.jdbc :as jdbc]
+            [hikari-cp.core :refer :all]))
 
 (defn sanitize-queries-param
   "Sanitizes the `queries` parameter. Clamps the value between 1 and 500.
@@ -38,31 +38,30 @@
     :delimiters "" ;; remove delimiters
     :maximum-pool-size 256}))
 
-;; MySQL database connection for java.jdbc "raw"
-;; https://github.com/clojure/java.jdbc/blob/master/doc/clojure/java/jdbc/ConnectionPooling.md
-(def db-spec-mysql-raw
-  {:classname "com.mysql.jdbc.Driver"
-   :subprotocol "mysql"
-   :subname "//127.0.0.1:3306/hello_world?jdbcCompliantTruncation=false&elideSetAutoCommits=true&useLocalSessionState=true&cachePrepStmts=true&cacheCallableStmts=true&alwaysSendSetIsolation=false&prepStmtCacheSize=4096&cacheServerConfiguration=true&prepStmtCacheSqlLimit=2048&zeroDateTimeBehavior=convertToNull&traceProtocol=false&useUnbufferedInput=false&useReadAheadInput=false&maintainTimeStats=false&useServerPrepStmts&cacheRSMetadata=true"
-   :user "benchmarkdbuser"
-   :password "benchmarkdbpass"})
-
-(defn pool
-  [spec]
-  (let [cpds (doto (ComboPooledDataSource.)
-               (.setDriverClass (:classname spec))
-               (.setJdbcUrl (str "jdbc:" (:subprotocol spec) ":" (:subname spec)))
-               (.setUser (:user spec))
-               (.setPassword (:password spec))
-               ;; expire excess connections after 30 minutes of inactivity:
-               (.setMaxIdleTimeExcessConnections (* 30 60))
-               ;; expire connections after 3 hours of inactivity:
-               (.setMaxIdleTime (* 3 60 60)))]
-    {:datasource cpds}))
-
-(def pooled-db (delay (pool db-spec-mysql-raw)))
-
-(defn db-mysql-raw [] @pooled-db)
+;; MySQL database connection for java.jdbc "raw" using HikariCP
+(def datasource-options-hikaricp {:auto-commit        true
+                                  :read-only          false
+                                  :connection-timeout 30000
+                                  :validation-timeout 5000
+                                  :idle-timeout       600000
+                                  :max-lifetime       1800000
+                                  :minimum-idle       10
+                                  :maximum-pool-size  256
+                                  :pool-name          "db-pool"
+                                  :adapter            "mysql"
+                                  :username           "benchmarkdbuser"
+                                  :password           "benchmarkdbpass"
+                                  :database-name      "hello_world"
+                                  :server-name        "127.0.0.1"
+                                  :port-number        3306
+                                  :register-mbeans    false})
+
+;; Create HikariCP-pooled "raw" jdbc data source
+(def db-spec-mysql-raw-hikaricp
+  (make-datasource datasource-options-hikaricp))
+
+;; Get a HikariCP-pooled "raw" jdbc connection
+(defn db-mysql-raw [] {:datasource db-spec-mysql-raw-hikaricp})
 
 ;; Set up entity World and the database representation
 (defentity world
@@ -146,30 +145,33 @@
   "Using Korma: Changes the :randomNumber of a number of world entities.
   Persists the changes to sql then returns the updated entities"
   [queries]
-(let [results (run-queries queries)]
-    (for [w results]
-      (update-in w [:randomNumber (inc (rand-int 9999))]
+  (let [results (map #(assoc % :randomNumber (inc (rand-int 9999))) (run-queries queries))]
+    (doseq [{:keys [id randomNumber]} results]
         (update world
-                (set-fields {:randomNumber (:randomNumber w)})
-                (where {:id [:id w]}))))
+              (set-fields {:randomNumber randomNumber})
+              (where {:id id})))
     results))
 
 (defn update-and-persist-raw
   "Using JDBC: Changes the :randomNumber of a number of world entities.
   Persists the changes to sql then returns the updated entities"
   [queries]
-(let [results (run-queries queries)]
-    (for [w results]
-      (update-in w [:randomNumber (inc (rand-int 9999))]
-        (jdbc/update! (db-mysql-raw) :world {:randomNumber (:randomNumber w)} ["id = ?" (:id w)])))
-    results))
-
-(def json-serialization
+  (let [world (map #(assoc % :randomnumber (inc (rand-int 9999))) (run-queries-raw queries))]
+    (doseq [{:keys [id randomnumber]} world]
+      (jdbc/update!
+       (db-mysql-raw)
+       :world {:randomnumber randomnumber}
+       ["id = ?" id]))
+    world))
+
+(defn json-serialization
   "Test 1: JSON serialization"
+  []
   (ring-resp/response {:message "Hello, World!"}))
 
-(def single-query-test
+(defn single-query-test
   "Test 2: Single database query"
+  []
   (ring-resp/response (first (run-queries 1))))
 
 (defn multiple-queries-test
@@ -180,8 +182,9 @@
       (run-queries)
       (ring-resp/response)))
 
-(def single-query-test-raw
+(defn single-query-test-raw
   "Test 2: Single database query (raw)"
+  []
   (-> 1
       (run-queries-raw)
       (first)
@@ -195,8 +198,9 @@
       (run-queries-raw)
       (ring-resp/response)))
 
-(def fortune-test
+(defn fortune-test
   "Test 4: Fortunes"
+  []
   (->
     (get-fortunes get-all-fortunes-korma)
     (fortunes-hiccup)
@@ -204,8 +208,9 @@
     (ring-resp/content-type "text/html")
     (ring-resp/charset "utf-8")))
 
-(def fortune-test-raw
+(defn fortune-test-raw
   "Test 4: Fortunes Raw"
+  []
   (->
     (get-fortunes get-all-fortunes-raw)
     (fortunes-hiccup)
@@ -239,19 +244,19 @@
 (defroutes app-routes
   (GET "/"                     [] "Hello, World!")
   (GET "/plaintext"            [] plaintext)
-  (GET "/json"                 [] json-serialization)
-  (GET "/db"                   [] single-query-test)
+  (GET "/json"                 [] (json-serialization))
+  (GET "/db"                   [] (single-query-test))
   (GET "/queries/:queries"     [queries] (multiple-queries-test queries))
-  (GET "/queries/"             [] (multiple-queries-test queries)) ; When param is omitted
-  (GET "/fortunes"             [] fortune-test)
+  (GET "/queries/"             [] (multiple-queries-test 1)) ; When param is omitted
+  (GET "/fortunes"             [] (fortune-test))
   (GET "/updates/:queries"     [queries] (db-updates queries))
-  (GET "/updates/"             [] (db-updates queries)) ; When param is omitted
-  (GET "/raw/db"               [] single-query-test-raw)
+  (GET "/updates/"             [] (db-updates 1)) ; When param is omitted
+  (GET "/raw/db"               [] (single-query-test-raw))
   (GET "/raw/queries/:queries" [queries] (multiple-queries-test-raw queries))
-  (GET "/raw/queries/"         [] (multiple-queries-test-raw queries)) ; When param is omitted
-  (GET "/raw/fortunes"         [] fortune-test-raw)
+  (GET "/raw/queries/"         [] (multiple-queries-test-raw 1)) ; When param is omitted
+  (GET "/raw/fortunes"         [] (fortune-test-raw))
   (GET "/raw/updates/:queries" [queries] (db-updates-raw queries))
-  (GET "/raw/updates/"         [] (db-updates-raw queries)) ; When param is omitted
+  (GET "/raw/updates/"         [] (db-updates-raw 1)) ; When param is omitted
   (route/not-found "Not Found"))
 
 (defn parse-port [s] 

+ 2 - 2
frameworks/Clojure/http-kit/setup.sh

@@ -1,8 +1,8 @@
 #!/bin/bash
 
-fw_depends leiningen java8
+fw_depends leiningen java
 
-sed -i 's|:subname "//.*:3306|:subname "//'"${DBHOST}"':3306|g' hello/src/hello/handler.clj
+sed -i 's|127.0.0.1|'"${DBHOST}"'|g' hello/src/hello/handler.clj
 
 cd hello
 lein clean

+ 2 - 21
frameworks/Clojure/luminus/README.md

@@ -1,6 +1,6 @@
 # Luminus Benchmarking Test
 
-This is the Luminus portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
+This is the [Luminus](http://www.luminusweb.net/) portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
 
 ### JSON Encoding Test
 
@@ -11,24 +11,5 @@ This is the Luminus portion of a [benchmarking test suite](../) comparing a vari
 * [Database test source](hello/src/hello/handler.clj)
 
 ## Infrastructure Software Versions
-The dependencies are documented in [project.clj](hello/project.clj),
-but the main ones are:
 
-* [Clojure 1.5.1](http://clojure.org/)
-* [lib-noir 0.5.5](https://github.com/noir-clojure/lib-noir)
-* [Compojure 1.1.5](https://github.com/weavejester/compojure)
-* [Cheshire 5.1.1](https://github.com/dakrone/cheshire), which in turn uses [Jackson](http://jackson.codehaus.org/)
-* [Korma 0.3.0-RC5](http://sqlkorma.com/)
-
-## Test URLs
-### JSON Encoding Test
-
-http://localhost/hello-compojure-standalone/json
-
-### Data-Store/Database Mapping Test
-
-http://localhost/hello-compojure-standalone/db
-
-### Variable Query Test
-
-http://localhost/hello-compojure-standalone/db/2
+The dependencies are documented in [project.clj](hello/project.clj).

+ 6 - 6
frameworks/Clojure/luminus/benchmark_config.json

@@ -3,26 +3,26 @@
   "tests": [{
     "default": {
       "setup_file": "setup",
-      "json_url": "/json",
+      "json_url": "/io/json",
+      "plaintext_url": "/io/plaintext",
       "db_url": "/db",
       "query_url": "/queries/",
       "fortune_url": "/fortunes",
       "update_url": "/updates/",
-      "plaintext_url": "/plaintext",
-      "port": 8080,
+      "port": 3000,
       "approach": "Realistic",
       "classification": "Platform",
-      "database": "MySQL",
+      "database": "Postgres",
       "framework": "luminus",
       "language": "Clojure",
       "orm": "Raw",
-      "platform": "http-kit",
+      "platform": "Immutant",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "luminus",
       "notes": "",
-      "versus": ""
+      "versus": "servlet"
     }
   }]
 }

+ 3 - 1
frameworks/Clojure/luminus/hello/.gitignore

@@ -6,5 +6,7 @@ pom.xml
 *.jar
 *.class
 /.lein-*
+profiles.clj
 /.env
-*.log
+.nrepl-port
+/log

+ 4 - 2
frameworks/Clojure/luminus/hello/README.md

@@ -1,5 +1,7 @@
 # hello
 
+generated using Luminus version "2.9.10.13"
+
 FIXME
 
 ## Prerequisites
@@ -12,8 +14,8 @@ You will need [Leiningen][1] 2.0 or above installed.
 
 To start a web server for the application, run:
 
-    lein ring server
+    lein run
 
 ## License
 
-Copyright © 2015 FIXME
+Copyright © 2016 FIXME

+ 10 - 0
frameworks/Clojure/luminus/hello/env/dev/clj/hello/dev_middleware.clj

@@ -0,0 +1,10 @@
+(ns hello.dev-middleware
+  (:require [ring.middleware.reload :refer [wrap-reload]]
+            [selmer.middleware :refer [wrap-error-page]]
+            [prone.middleware :refer [wrap-exceptions]]))
+
+(defn wrap-dev [handler]
+  (-> handler
+      wrap-reload
+      wrap-error-page
+      wrap-exceptions))

+ 11 - 0
frameworks/Clojure/luminus/hello/env/dev/clj/hello/env.clj

@@ -0,0 +1,11 @@
+(ns hello.env
+  (:require [selmer.parser :as parser]
+            [clojure.tools.logging :as log]
+            [hello.dev-middleware :refer [wrap-dev]]))
+
+(def defaults
+  {:init
+   (fn []
+     (parser/cache-off!)
+     (log/info "\n-=[hello started successfully using the development profile]=-"))
+   :middleware wrap-dev})

+ 0 - 34
frameworks/Clojure/luminus/hello/env/dev/clj/hello/repl.clj

@@ -1,34 +0,0 @@
-(ns hello.repl
-  (:use hello.handler
-    ring.server.standalone
-    [ring.middleware file-info file]))
-
-(defonce server (atom nil))
-
-(defn get-handler []
-  ;; #'app expands to (var app) so that when we reload our code,
-  ;; the server is forced to re-resolve the symbol in the var
-  ;; rather than having its own copy. When the root binding
-  ;; changes, the server picks it up without having to restart.
-  (-> #'app
-      ; Makes static assets in $PROJECT_DIR/resources/public/ available.
-      (wrap-file "resources")
-      ; Content-Type, Content-Length, and Last Modified headers for files in body
-      (wrap-file-info)))
-
-(defn start-server
-  "used for starting the server in development mode from REPL"
-  [& [port]]
-  (let [port (if port (Integer/parseInt port) 3000)]
-    (reset! server
-            (serve (get-handler)
-                   {:port port
-                    :init init
-                    :auto-reload? true
-                    :destroy destroy
-                    :join? false}))
-    (println (str "You can view the site at http://localhost:" port))))
-
-(defn stop-server []
-  (.stop @server)
-  (reset! server nil))

+ 15 - 0
frameworks/Clojure/luminus/hello/env/dev/clj/user.clj

@@ -0,0 +1,15 @@
+(ns user
+  (:require [mount.core :as mount]
+            hello.core))
+
+(defn start []
+  (mount/start-without #'hello.core/repl-server))
+
+(defn stop []
+  (mount/stop-except #'hello.core/repl-server))
+
+(defn restart []
+  (stop)
+  (start))
+
+

+ 5 - 0
frameworks/Clojure/luminus/hello/env/dev/resources/config.edn

@@ -0,0 +1,5 @@
+{:dev true
+ :port 3000
+ ;; when :nrepl-port is set the application starts the nREPL server on load
+ :nrepl-port 7000
+ :database-url "jdbc:postgresql://127.0.0.1:5432/hello_world?user=benchmarkdbuser&password=benchmarkdbpass&jdbcCompliantTruncation=false&elideSetAutoCommits=true&useLocalSessionState=true&cachePrepStmts=true&cacheCallableStmts=true&alwaysSendSetIsolation=false&prepStmtCacheSize=4096&cacheServerConfiguration=true&prepStmtCacheSqlLimit=2048&zeroDateTimeBehavior=convertToNull&traceProtocol=false&useUnbufferedInput=false&useReadAheadInput=false&maintainTimeStats=false&useServerPrepStmts&cacheRSMetadata=true"}

+ 25 - 0
frameworks/Clojure/luminus/hello/env/dev/resources/log4j.properties

@@ -0,0 +1,25 @@
+### stdout appender
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=[%d][%p][%c] %m%n
+
+### rolling file appender
+log4j.appender.R=org.apache.log4j.RollingFileAppender
+log4j.appender.R.File=./log/hello.log
+
+log4j.appender.R.MaxFileSize=100KB
+log4j.appender.R.MaxBackupIndex=20
+
+log4j.appender.R.layout=org.apache.log4j.PatternLayout
+log4j.appender.R.layout.ConversionPattern=[%d][%p][%c] %m%n
+
+### suppress 3rd party debug logs
+log4j.logger.org.xnio.nio=INFO
+log4j.logger.com.zaxxer.hikari=INFO
+
+
+
+### root logger sets the minimum logging level
+### and aggregates the appenders
+log4j.rootLogger=DEBUG, stdout, R

+ 8 - 0
frameworks/Clojure/luminus/hello/env/prod/clj/hello/env.clj

@@ -0,0 +1,8 @@
+(ns hello.env
+  (:require [clojure.tools.logging :as log]))
+
+(def defaults
+  {:init
+   (fn []
+     (log/info "\n-=[hello started successfully]=-"))
+   :middleware identity})

+ 3 - 0
frameworks/Clojure/luminus/hello/env/prod/resources/config.edn

@@ -0,0 +1,3 @@
+{:production true
+ :port 3000
+ :database-url "jdbc:postgresql://127.0.0.1:5432/hello_world?user=benchmarkdbuser&password=benchmarkdbpass&jdbcCompliantTruncation=false&elideSetAutoCommits=true&useLocalSessionState=true&cachePrepStmts=true&cacheCallableStmts=true&alwaysSendSetIsolation=false&prepStmtCacheSize=4096&cacheServerConfiguration=true&prepStmtCacheSqlLimit=2048&zeroDateTimeBehavior=convertToNull&traceProtocol=false&useUnbufferedInput=false&useReadAheadInput=false&maintainTimeStats=false&useServerPrepStmts&cacheRSMetadata=true"}

+ 25 - 0
frameworks/Clojure/luminus/hello/env/prod/resources/log4j.properties

@@ -0,0 +1,25 @@
+### stdout appender
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=[%d][%p][%c] %m%n
+
+### rolling file appender
+log4j.appender.R=org.apache.log4j.RollingFileAppender
+log4j.appender.R.File=./log/hello.log
+
+log4j.appender.R.MaxFileSize=100KB
+log4j.appender.R.MaxBackupIndex=20
+
+log4j.appender.R.layout=org.apache.log4j.PatternLayout
+log4j.appender.R.layout.ConversionPattern=[%d][%p][%c] %m%n
+
+### suppress 3rd party debug logs
+log4j.logger.org.xnio.nio=INFO
+log4j.logger.com.zaxxer.hikari=INFO
+
+
+
+### root logger sets the minimum logging level
+### and aggregates the appenders
+log4j.rootLogger=INFO, stdout, R

+ 3 - 0
frameworks/Clojure/luminus/hello/env/test/resources/config.edn

@@ -0,0 +1,3 @@
+{:test true
+ :port 3001
+ :nrepl-port 7001} ;; when :nrepl-port is set the application starts the nREPL server on load

+ 56 - 39
frameworks/Clojure/luminus/hello/project.clj

@@ -1,49 +1,66 @@
-(defproject hello "luminus"
+(defproject hello "0.1.0-SNAPSHOT"
 
-  :description "Luminus framework benchmarks"
-  :url "https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/Clojure/luminus"
+  :description "FIXME: write description"
+  :url "http://example.com/FIXME"
 
-  :dependencies [[org.clojure/clojure "1.6.0"]
-                 [ring-server "0.4.0"]
-                 [selmer "0.8.2"]
-                 [com.taoensso/timbre "3.4.0"]
+  :dependencies [[org.clojure/clojure "1.8.0"]
+                 [selmer "1.0.2"]
+                 [markdown-clj "0.9.86"]
+                 [ring-middleware-format "0.7.0"]
+                 [metosin/ring-http-response "0.6.5"]
+                 [bouncer "1.0.0"]
+                 [org.webjars/bootstrap "4.0.0-alpha.2"]
+                 [org.webjars/font-awesome "4.5.0"]
+                 [org.webjars.bower/tether "1.1.1"]
+                 [org.webjars/jquery "2.2.1"]
+                 [org.clojure/tools.logging "0.3.1"]
                  [com.taoensso/tower "3.0.2"]
-                 [markdown-clj "0.9.65"]
-                 [environ "1.0.0"]
-                 [im.chit/cronj "1.4.3"]
-                 [compojure "1.3.3"]
-                 [ring/ring-defaults "0.1.4"]
-                 [ring/ring-session-timeout "0.1.0"]
-                 [ring-middleware-format "0.5.0"]
-                 [noir-exception "0.2.3"]
-                 [bouncer "0.3.2"]
-                 [prone "0.8.1"]
-                 [org.clojure/tools.nrepl "0.2.8"]
-                 [yesql "0.5.0-rc2"]
-                 [mysql/mysql-connector-java "5.1.6"]
-                 [c3p0/c3p0 "0.9.1.2"]
-                 [http-kit "2.1.19"]
-                 [org.clojure/tools.cli "0.2.1"]]
+                 [compojure "1.5.0"]
+                 [ring-webjars "0.1.1"]
+                 [ring/ring-defaults "0.2.0"]
+                 [mount "0.1.10"]
+                 [cprop "0.1.6"]
+                 [org.clojure/tools.cli "0.3.3"]
+                 [luminus-nrepl "0.1.4"]
+                 [org.webjars/webjars-locator-jboss-vfs "0.1.0"]
+                 [luminus-immutant "0.1.9"]
+                 [luminus-migrations "0.1.0"]
+                 [conman "0.4.5"]
+                 [org.postgresql/postgresql "9.4-1206-jdbc4"]
+                 [luminus-log4j "0.1.3"]]
 
   :min-lein-version "2.0.0"
-  :uberjar-name "hello.jar"
-  :jvm-opts ["-server"]
 
-  :main hello.core
+  :jvm-opts ["-server" "-Dconf=.lein-env"]
+  :source-paths ["src/clj"]
+  :resource-paths ["resources"]
 
-  :plugins [[lein-ring "0.9.1"]
-            [lein-environ "1.0.0"]]
+  :main hello.core
+  :migratus {:store :database :db ~(get (System/getenv) "DATABASE_URL")}
 
+  :plugins [[lein-cprop "1.0.1"]
+            [migratus-lein "0.2.6"]]
   :profiles
   {:uberjar {:omit-source true
-             :env {:production true}
-             :aot :all}
-   :dev {:dependencies [[ring-mock "0.1.5"]
-                        [ring/ring-devel "1.3.2"]
-                        [pjstadig/humane-test-output "0.7.0"]]
-         :source-paths ["env/dev/clj"]
-
-         :repl-options {:init-ns hello.repl}
-         :injections [(require 'pjstadig.humane-test-output)
-                      (pjstadig.humane-test-output/activate!)]
-         :env {:dev true}}})
+
+             :aot :all
+             :uberjar-name "hello.jar"
+             :source-paths ["env/prod/clj"]
+             :resource-paths ["env/prod/resources"]}
+   :dev           [:project/dev :profiles/dev]
+   :test          [:project/test :profiles/test]
+   :project/dev  {:dependencies [[prone "1.0.2"]
+                                 [ring/ring-mock "0.3.0"]
+                                 [ring/ring-devel "1.4.0"]
+                                 [pjstadig/humane-test-output "0.7.1"]
+                                 [mvxcvi/puget "1.0.0"]]
+
+
+                  :source-paths ["env/dev/clj" "test/clj"]
+                  :resource-paths ["env/dev/resources"]
+                  :repl-options {:init-ns user}
+                  :injections [(require 'pjstadig.humane-test-output)
+                               (pjstadig.humane-test-output/activate!)]}
+   :project/test {:resource-paths ["env/dev/resources" "env/test/resources"]}
+   :profiles/dev {}
+   :profiles/test {}})

+ 34 - 0
frameworks/Clojure/luminus/hello/resources/docs/docs.md

@@ -0,0 +1,34 @@
+<div class="bs-callout bs-callout-danger">
+
+### Database Configuration is Required
+
+If you haven't already, then please follow the steps below to configure your database connection and run the necessary migrations.
+
+* Create the database for your application.
+* Update the connection URL in the `profiles.clj` file with your database name and login.
+* Run `lein run migrate` in the root of the project to create the tables.
+* Restart the application.
+
+</div>
+
+
+### Managing Your Middleware
+
+Request middleware functions are located under the `hello.middleware` namespace.
+
+This namespace is reserved for any custom middleware for the application. Some default middleware is
+already defined here. The middleware is assembled in the `wrap-base` function.
+
+Middleware used for development is placed in the `hello.dev-middleware` namespace found in
+the `env/dev/clj/` source path.
+
+### Here are some links to get started
+
+1. [HTML templating](http://www.luminusweb.net/docs/html_templating.md)
+2. [Accessing the database](http://www.luminusweb.net/docs/database.md)
+3. [Setting response types](http://www.luminusweb.net/docs/responses.md)
+4. [Defining routes](http://www.luminusweb.net/docs/routes.md)
+5. [Adding middleware](http://www.luminusweb.net/docs/middleware.md)
+6. [Sessions and cookies](http://www.luminusweb.net/docs/sessions_cookies.md)
+7. [Security](http://www.luminusweb.net/docs/security.md)
+8. [Deploying the application](http://www.luminusweb.net/docs/deployment.md)

+ 28 - 1
frameworks/Clojure/luminus/hello/resources/public/css/screen.css

@@ -2,5 +2,32 @@ html,
 body {
 	font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
     height: 100%;
-    padding-top: 40px;
 }
+.navbar {
+  margin-bottom: 10px;
+}
+.navbar-brand {
+  float: none;
+}
+.navbar-nav .nav-item {
+  float: none;
+}
+.navbar-divider,
+.navbar-nav .nav-item+.nav-item,
+.navbar-nav .nav-link + .nav-link {
+  margin-left: 0;
+}
+@media (min-width: 34em) {
+  .navbar-brand {
+    float: left;
+  }
+  .navbar-nav .nav-item {
+    float: left;
+  }
+  .navbar-divider,
+  .navbar-nav .nav-item+.nav-item,
+  .navbar-nav .nav-link + .nav-link {
+    margin-left: 1rem;
+  }
+}
+

+ 0 - 0
frameworks/PHP/lithium/app/resources/g11n/empty → frameworks/Clojure/luminus/hello/resources/public/favicon.ico


+ 9 - 15
frameworks/Clojure/luminus/hello/resources/sql/queries.sql

@@ -1,20 +1,14 @@
---name: get-world
--- Query a World record from the database
-SELECT * FROM world
-WHERE id = :id
-
---name: get-all-fortunes
+--:name get-all-fortunes :? :*
 -- select all records from the fortune table
-SELECT * FROM fortune
+SELECT * FROM "Fortune"
 
---name: update-world<!
+-- :name update-world! :! :1
 -- update an existing world record
-UPDATE world
-SET randomNumber = :randomNumber
+UPDATE "World"
+SET "randomnumber" = :randomNumber
 WHERE id = :id
 
---name: get-all-fortunes
--- query all fortune records
-SELECT id, message FROM fortune
-
-
+-- :name get-world :? :1
+-- get world by id
+SELECT * FROM "World"
+WHERE id = :id

+ 4 - 0
frameworks/Clojure/luminus/hello/resources/templates/about.html

@@ -0,0 +1,4 @@
+{% extends "base.html" %}
+{% block content %}
+  <p>this is the story of hello... work in progress</p>
+{% endblock %}

+ 56 - 0
frameworks/Clojure/luminus/hello/resources/templates/error.html

@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Something bad happened</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    {% style "/assets/bootstrap/css/bootstrap.min.css" %}
+    {% style "/assets/bootstrap/css/bootstrap-theme.min.css" %}
+    <style type="text/css">
+        html {
+            height: 100%;
+            min-height: 100%;
+            min-width: 100%;
+            overflow: hidden;
+            width: 100%;
+        }
+        html body {
+            height: 100%;
+            margin: 0;
+            padding: 0;
+            width: 100%;
+        }
+        html .container-fluid {
+            display: table;
+            height: 100%;
+            padding: 0;
+            width: 100%;
+        }
+        html .row-fluid {
+            display: table-cell;
+            height: 100%;
+            vertical-align: middle;
+        }
+    </style>
+</head>
+<body>
+<div class="container-fluid">
+    <div class="row-fluid">
+        <div class="col-lg-12">
+            <div class="centering text-center">
+                <div class="text-center">
+                    <h1><span class="text-danger">Error: {{status}}</span></h1>
+                    <hr>
+                    {% if title %}
+                    <h2 class="without-margin">{{title}}</h2>
+                    {% endif %}
+                    {% if message %}
+                    <h4 class="text-danger">{{message}}</h4>
+                    {% endif %}
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+</body>
+</html>

+ 0 - 3
frameworks/Clojure/luminus/hello/resources/templates/home.html

@@ -1,7 +1,5 @@
 {% extends "base.html" %}
-
 {% block content %}
-
 <table>
   <tr>
     <th>id</th>
@@ -14,5 +12,4 @@
   </tr>
   {% endfor %}
 </table>
-
 {% endblock %}

Some files were not shown because too many files changed in this diff