Browse Source

Merge branch 'master' of github-msmith:TechEmpower/FrameworkBenchmarks

msmith-techempower 10 years ago
parent
commit
a70779383e

+ 2 - 2
frameworks/C++/ULib/benchmark_config

@@ -2,13 +2,13 @@
   "framework": "ULib",
   "framework": "ULib",
   "tests": [{
   "tests": [{
     "default": {
     "default": {
-      "setup_file": "setup_mysql",
+      "setup_file": "setup",
       "json_url": "/json",
       "json_url": "/json",
       "plaintext_url": "/plaintext",
       "plaintext_url": "/plaintext",
       "port": 8080,
       "port": 8080,
       "approach": "Realistic",
       "approach": "Realistic",
       "classification": "Platform",
       "classification": "Platform",
-      "database": "MySQL",
+      "database": "None",
       "framework": "ULib",
       "framework": "ULib",
       "language": "C++",
       "language": "C++",
       "orm": "Micro",
       "orm": "Micro",

+ 4 - 4
frameworks/C++/ULib/install.sh

@@ -41,12 +41,12 @@ if [ ! -f "benchmark.cfg" ]; then
   cat <<EOF >benchmark.cfg
   cat <<EOF >benchmark.cfg
 userver {
 userver {
  PORT 8080
  PORT 8080
- PREFORK_CHILD 8
- LISTEN_BACKLOG 8192
- MAX_KEEP_ALIVE 8192
+ PREFORK_CHILD 4
+ MAX_KEEP_ALIVE 1023
+ LISTEN_BACKLOG 16384
+ CLIENT_FOR_PARALLELIZATION 256
  ORM_DRIVER "mysql pgsql sqlite"
  ORM_DRIVER "mysql pgsql sqlite"
  DOCUMENT_ROOT $ULIB_DOCUMENT_ROOT
  DOCUMENT_ROOT $ULIB_DOCUMENT_ROOT
-#PID_FILE ${ULIB_ROOT}/userver_tcp.pid
 }
 }
 EOF
 EOF
 fi
 fi

+ 9 - 0
frameworks/C++/ULib/setup.sh

@@ -0,0 +1,9 @@
+#!/bin/bash
+
+export UMEMPOOL="176,100,0,37,1160,155,-17,-22,40"
+
+# 1. Change ULib Server configuration
+sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g" ${IROOT}/ULib/benchmark.cfg
+
+# 2. Start ULib Server (userver_tcp)
+${IROOT}/ULib/bin/userver_tcp -c ${IROOT}/ULib/benchmark.cfg &

+ 2 - 1
frameworks/C++/ULib/setup_mysql.sh

@@ -1,9 +1,10 @@
 #!/bin/bash
 #!/bin/bash
 
 
-export UMEMPOOL="545,0,0,37,8465,0,-17,-22,34"
 export ORM_DRIVER="mysql"
 export ORM_DRIVER="mysql"
 export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass character-set=utf8 dbname=hello_world"
 export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass character-set=utf8 dbname=hello_world"
 
 
+export UMEMPOOL="176,100,0,37,1160,155,-17,-22,40"
+
 # 1. Change ULib Server configuration
 # 1. Change ULib Server configuration
 sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g" $IROOT/ULib/benchmark.cfg
 sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g" $IROOT/ULib/benchmark.cfg
 
 

+ 2 - 1
frameworks/C++/ULib/setup_postgres.sh

@@ -1,9 +1,10 @@
 #!/bin/bash
 #!/bin/bash
 
 
-export UMEMPOOL="545,0,0,37,8465,0,-17,-22,34"
 export ORM_DRIVER="pgsql"
 export ORM_DRIVER="pgsql"
 export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass dbname=hello_world client_encoding=UTF8"
 export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass dbname=hello_world client_encoding=UTF8"
 
 
+export UMEMPOOL="176,100,0,37,1160,155,-17,-22,40"
+
 # 1. Change ULib Server configuration
 # 1. Change ULib Server configuration
 sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g" $IROOT/ULib/benchmark.cfg
 sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g" $IROOT/ULib/benchmark.cfg
 
 

+ 2 - 1
frameworks/C++/ULib/setup_sqlite.sh

@@ -1,9 +1,10 @@
 #!/bin/bash
 #!/bin/bash
 
 
-export UMEMPOOL="545,0,0,37,8465,0,-17,-22,34"
 export ORM_DRIVER="sqlite"
 export ORM_DRIVER="sqlite"
 export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass character-set=utf8 dbname=${ULIB_ROOT}/db/%.*s"
 export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass character-set=utf8 dbname=${ULIB_ROOT}/db/%.*s"
 
 
+export UMEMPOOL="176,100,0,37,1160,155,-17,-22,40"
+
 # 1. Change ULib Server configuration
 # 1. Change ULib Server configuration
 sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g" ${IROOT}/ULib/benchmark.cfg
 sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g" ${IROOT}/ULib/benchmark.cfg
 
 

+ 32 - 22
frameworks/C++/ULib/src/db.usp

@@ -1,48 +1,58 @@
+<!--#
+Test type 2: Single database query
+TechEmpower Web Framework Benchmarks
+-->
 <!--#declaration
 <!--#declaration
 #include "world.h"
 #include "world.h"
 
 
-#ifndef AS_cpoll_cppsp_DO
-static UValue* pvalue;
-#endif
 static World*         pworld_db;
 static World*         pworld_db;
 static UOrmSession*   psql_db;
 static UOrmSession*   psql_db;
 static UOrmStatement* pstmt_db;
 static UOrmStatement* pstmt_db;
 
 
-static void usp_init_db()
-{
-   U_TRACE(5, "::usp_init_db()")
-
-   pworld_db = U_NEW(World);
-
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
-   pvalue = U_NEW(UValue(OBJECT_VALUE));
+static UValue* pvalue;
 #endif
 #endif
-}
 
 
 static void usp_fork_db()
 static void usp_fork_db()
 {
 {
    U_TRACE(5, "::usp_fork_db()")
    U_TRACE(5, "::usp_fork_db()")
 
 
-   psql_db  = U_NEW(UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
-   pstmt_db = U_NEW(UOrmStatement(*psql_db, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
+   psql_db = U_NEW(UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
+
+   if (psql_db->isReady())
+      {
+      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");
+
+      pworld_db = U_NEW(World);
 
 
-   if (pstmt_db == 0) U_ERROR("usp_fork_db(): we cound't connect to db");
+      pstmt_db->use( pworld_db->id);
+      pstmt_db->into(pworld_db->randomNumber);
 
 
-   pstmt_db->use( pworld_db->id);
-   pstmt_db->into(pworld_db->randomNumber);
+#  ifndef AS_cpoll_cppsp_DO
+      pvalue = U_NEW(UValue(OBJECT_VALUE));
+#  endif
+      }
 }
 }
 
 
+#ifdef DEBUG
 static void usp_end_db()
 static void usp_end_db()
 {
 {
    U_TRACE(5, "::usp_end_db()")
    U_TRACE(5, "::usp_end_db()")
 
 
-   delete pstmt_db;
-   delete psql_db;
-   delete pworld_db;
-#ifndef AS_cpoll_cppsp_DO
-   delete pvalue;
-#endif
+   if (pstmt_db)
+      {
+      delete  pstmt_db;
+      delete   psql_db;
+      delete pworld_db;
+
+#  ifndef AS_cpoll_cppsp_DO
+      delete pvalue;
+#  endif
+      }
 }
 }
+#endif
 -->
 -->
 <!--#header
 <!--#header
 Content-Type: application/json; charset=UTF-8
 Content-Type: application/json; charset=UTF-8

+ 25 - 15
frameworks/C++/ULib/src/fortune.usp

@@ -1,43 +1,53 @@
+<!--#
+Test type 4: Fortunes
+TechEmpower Web Framework Benchmarks
+-->
 <!--#declaration
 <!--#declaration
 #include "fortune.h"
 #include "fortune.h"
 
 
-static UOrmSession*       psql_fortune;
-static UOrmStatement*     pstmt_fortune;
 static Fortune*           pfortune;
 static Fortune*           pfortune;
 static UString*           pmessage;
 static UString*           pmessage;
+static UOrmSession*       psql_fortune;
+static UOrmStatement*     pstmt_fortune;
 static UVector<Fortune*>* pvfortune;
 static UVector<Fortune*>* pvfortune;
 
 
-static void usp_init_fortune()
-{
-   U_TRACE(5, "::usp_init_fortune()")
-
-   pfortune  = U_NEW(Fortune);
-   pvfortune = U_NEW(UVector<Fortune*>);
-   pmessage  = U_NEW(U_STRING_FROM_CONSTANT("Additional fortune added at request time."));
-}
-
 static void usp_fork_fortune()
 static void usp_fork_fortune()
 {
 {
    U_TRACE(5, "::usp_fork_fortune()")
    U_TRACE(5, "::usp_fork_fortune()")
 
 
-   psql_fortune  = U_NEW(UOrmSession(U_CONSTANT_TO_PARAM("fortune")));
-   pstmt_fortune = U_NEW(UOrmStatement(*psql_fortune, U_CONSTANT_TO_PARAM("SELECT id, message FROM Fortune")));
+   psql_fortune = U_NEW(UOrmSession(U_CONSTANT_TO_PARAM("fortune")));
+
+   if (psql_fortune->isReady())
+      {
+      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");
+
+      pfortune = U_NEW(Fortune);
 
 
-   if (pstmt_fortune == 0) U_ERROR("usp_fork_fortune(): we cound't connect to db");
+      pstmt_fortune->into(*pfortune);
 
 
-   pstmt_fortune->into(*pfortune);
+      pmessage  = U_NEW(U_STRING_FROM_CONSTANT("Additional fortune added at request time."));
+      pvfortune = U_NEW(UVector<Fortune*>);
+      }
 }
 }
 
 
+#ifdef DEBUG
 static void usp_end_fortune()
 static void usp_end_fortune()
 {
 {
    U_TRACE(5, "::usp_end_fortune()")
    U_TRACE(5, "::usp_end_fortune()")
 
 
+   if (pstmt_fortune)
+   {
    delete pstmt_fortune;
    delete pstmt_fortune;
+
    delete psql_fortune;
    delete psql_fortune;
    delete pvfortune;
    delete pvfortune;
    delete pfortune;
    delete pfortune;
    delete pmessage;
    delete pmessage;
+   }
 }
 }
+#endif
 -->
 -->
 <!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><!--#code
 <!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><!--#code
 Fortune* elem;
 Fortune* elem;

+ 6 - 0
frameworks/C++/ULib/src/json.usp

@@ -1,3 +1,7 @@
+<!--#
+Test type 1: JSON serialization
+TechEmpower Web Framework Benchmarks
+-->
 <!--#declaration
 <!--#declaration
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
 #undef AS_cpoll_cppsp_DO
 #undef AS_cpoll_cppsp_DO
@@ -19,6 +23,7 @@ static void usp_init_json()
 #endif
 #endif
 }
 }
 
 
+#ifdef DEBUG
 static void usp_end_json()
 static void usp_end_json()
 {
 {
    U_TRACE(5, "::usp_end_json()")
    U_TRACE(5, "::usp_end_json()")
@@ -28,6 +33,7 @@ static void usp_end_json()
    delete pvalue;
    delete pvalue;
 #endif
 #endif
 }
 }
+#endif
 -->
 -->
 <!--#header
 <!--#header
 Content-Type: application/json; charset=UTF-8
 Content-Type: application/json; charset=UTF-8

+ 32 - 21
frameworks/C++/ULib/src/query.usp

@@ -1,51 +1,62 @@
+<!--#
+Test type 3: Multiple database queries
+TechEmpower Web Framework Benchmarks
+-->
 <!--#declaration
 <!--#declaration
 #include "world.h"
 #include "world.h"
 
 
-#ifndef AS_cpoll_cppsp_DO
-static UValue* pvalue;
-#endif
+static World*           pworld_query;
 static UOrmSession*     psql_query;
 static UOrmSession*     psql_query;
 static UOrmStatement*   pstmt_query;
 static UOrmStatement*   pstmt_query;
-static World*           pworld_query;
 static UVector<World*>* pvworld_query;
 static UVector<World*>* pvworld_query;
 
 
-static void usp_init_query()
-{
-   U_TRACE(5, "::usp_init_query()")
-
-   pworld_query  = U_NEW(World);
-   pvworld_query = U_NEW(UVector<World*>(500));
-
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
-   pvalue = U_NEW(UValue(ARRAY_VALUE));
+static UValue* pvalue;
 #endif
 #endif
-}
 
 
 static void usp_fork_query()
 static void usp_fork_query()
 {
 {
    U_TRACE(5, "::usp_fork_query()")
    U_TRACE(5, "::usp_fork_query()")
 
 
-   psql_query  = U_NEW(UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
-   pstmt_query = U_NEW(UOrmStatement(*psql_query, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
+   psql_query = U_NEW(UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
+
+   if (psql_query->isReady())
+      {
+      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");
+
+      pworld_query = U_NEW(World);
+
+      pstmt_query->use( pworld_query->id);
+      pstmt_query->into(pworld_query->randomNumber);
 
 
-   if (pstmt_query == 0) U_ERROR("usp_fork_query(): we cound't connect to db");
+      pvworld_query = U_NEW(UVector<World*>(500));
 
 
-   pstmt_query->use( pworld_query->id);
-   pstmt_query->into(pworld_query->randomNumber);
+#  ifndef AS_cpoll_cppsp_DO
+      pvalue = U_NEW(UValue(ARRAY_VALUE));
+#  endif
+      }
 }
 }
 
 
+#ifdef DEBUG
 static void usp_end_query()
 static void usp_end_query()
 {
 {
    U_TRACE(5, "::usp_end_query()")
    U_TRACE(5, "::usp_end_query()")
 
 
-   delete pstmt_query;
-   delete psql_query;
+   if (pstmt_query)
+   {
+   delete   pstmt_query;
+   delete    psql_query;
    delete pvworld_query;
    delete pvworld_query;
-   delete pworld_query;
+   delete  pworld_query;
+
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
    delete pvalue;
    delete pvalue;
 #endif
 #endif
+   }
 }
 }
+#endif
 -->
 -->
 <!--#args
 <!--#args
 queries;
 queries;

+ 43 - 33
frameworks/C++/ULib/src/update.usp

@@ -1,26 +1,19 @@
+<!--#
+Test type 5: Database updates
+TechEmpower Web Framework Benchmarks
+-->
 <!--#declaration
 <!--#declaration
 #include "world.h"
 #include "world.h"
 
 
-#ifndef AS_cpoll_cppsp_DO
-static UValue* pvalue;
-#endif
+static World*           pworld_update;
 static UOrmSession*     psql_update;
 static UOrmSession*     psql_update;
 static UOrmStatement*   pstmt1;
 static UOrmStatement*   pstmt1;
 static UOrmStatement*   pstmt2;
 static UOrmStatement*   pstmt2;
-static World*           pworld_update;
 static UVector<World*>* pvworld_update;
 static UVector<World*>* pvworld_update;
 
 
-static void usp_init_update()
-{
-   U_TRACE(5, "::usp_init_update()")
-
-   pworld_update  = U_NEW(World);
-   pvworld_update = U_NEW(UVector<World*>(500));
-
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
-   pvalue = U_NEW(UValue(ARRAY_VALUE));
+static UValue* pvalue;
 #endif
 #endif
-}
 
 
 static void usp_fork_update()
 static void usp_fork_update()
 {
 {
@@ -28,33 +21,52 @@ static void usp_fork_update()
 
 
    psql_update = U_NEW(UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
    psql_update = U_NEW(UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
 
 
-   pstmt1 = U_NEW(UOrmStatement(*psql_update, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
-   pstmt2 = U_NEW(UOrmStatement(*psql_update, U_CONSTANT_TO_PARAM("UPDATE World SET randomNumber = ? WHERE id = ?")));
-
-   if (pstmt1 == 0 ||
-       pstmt2 == 0)
+   if (psql_update->isReady())
       {
       {
-      U_ERROR("usp_fork_update(): we cound't connect to db");
-      }
+      pstmt1 = U_NEW(UOrmStatement(*psql_update, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
+      pstmt2 = U_NEW(UOrmStatement(*psql_update, U_CONSTANT_TO_PARAM("UPDATE World SET randomNumber = ? WHERE id = ?")));
 
 
-   pstmt1->use( pworld_update->id);
-   pstmt1->into(pworld_update->randomNumber);
-   pstmt2->use( pworld_update->randomNumber, pworld_update->id);
+      if (pstmt1 == 0 ||
+          pstmt2 == 0)
+         {
+         U_ERROR("usp_fork_update(): we cound't connect to db");
+         }
+
+      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));
+#  endif
+      }
 }
 }
 
 
+#ifdef DEBUG
 static void usp_end_update()
 static void usp_end_update()
 {
 {
    U_TRACE(5, "::usp_end_update()")
    U_TRACE(5, "::usp_end_update()")
 
 
-   delete pstmt1;
-   delete pstmt2;
-   delete psql_update;
-   delete pvworld_update;
-   delete pworld_update;
-#ifndef AS_cpoll_cppsp_DO
-   delete pvalue;
-#endif
+   if (pstmt1 &&
+       pstmt2)
+      {
+      delete pstmt1;
+      delete pstmt2;
+
+      delete    psql_update;
+      delete pvworld_update;
+      delete  pworld_update;
+
+#  ifndef AS_cpoll_cppsp_DO
+      delete pvalue;
+#  endif
+      }
 }
 }
+#endif
 -->
 -->
 <!--#args
 <!--#args
 queries;
 queries;
@@ -78,8 +90,6 @@ while (true)
 
 
    pstmt1->execute();
    pstmt1->execute();
 
 
-   U_INTERNAL_DUMP("pworld_update->randomNumber = %u", pworld_update->randomNumber)
-
    pworld_update->randomNumber = u_get_num_random(10000);
    pworld_update->randomNumber = u_get_num_random(10000);
 
 
    pstmt2->execute();
    pstmt2->execute();

+ 35 - 67
frameworks/C++/wt/benchmark.cpp

@@ -91,57 +91,38 @@ public:
     }
     }
 };
 };
 
 
-std::mutex mtx;
-
-struct DbStruct {
-#ifndef BENCHMARK_USE_POSTGRES
-  Wt::Dbo::backend::MySQL connection;
+class MyConnection : public
+#ifdef BENCHMARK_USE_POSTGRES
+  Wt::Dbo::backend::Postgres
 #else
 #else
-  Wt::Dbo::backend::Postgres connection;
+  Wt::Dbo::backend::MySQL
 #endif
 #endif
-  Wt::Dbo::Session session;
-  Wt::Dbo::Transaction *transaction;
-
-  boost::taus88 rng;
-  boost::random::uniform_int_distribution<int> distribution;
-
-#ifndef BENCHMARK_USE_POSTGRES
-  DbStruct() : connection("hello_world", "benchmarkdbuser", "benchmarkdbpass", "INSERT_DB_HOST_HERE", 3306),
+{
+public:
+#ifdef BENCHMARK_USE_POSTGRES
+  MyConnection(const std::string &db) :
+  Wt::Dbo::backend::Postgres(db) {}
 #else
 #else
-  DbStruct() : connection("host=INSERT_DB_HOST_HERE port=5432 user=benchmarkdbuser password=benchmarkdbpass dbname=hello_world"),
+  MyConnection(const std::string &db, const std::string &dbuser, const std::string &dbpasswd, const std::string &dbhost, unsigned int dbport) :
+  Wt::Dbo::backend::MySQL(db, dbuser, dbpasswd, dbhost, dbport) {}
 #endif
 #endif
-      rng(clock()),
-      distribution(1, 10000) {
-    session.setConnection(connection);
-    session.mapClass<World>("world");
-    session.mapClass<Fortune>("fortune");
-    transaction = new Wt::Dbo::Transaction(session);
-  }
-
-  ~DbStruct() {
-    delete transaction;
-  }
 
 
-  int rand() {
-    return distribution(rng);
-  }
+  virtual void startTransaction() { }
+  virtual void commitTransaction() { }
+  virtual void rollbackTransaction() { }
 };
 };
 
 
-struct DbStructNoTransaction {
-#ifndef BENCHMARK_USE_POSTGRES
-  Wt::Dbo::backend::MySQL connection;
-#else
-  Wt::Dbo::backend::Postgres connection;
-#endif
+struct DbStruct {
+  MyConnection connection;
   Wt::Dbo::Session session;
   Wt::Dbo::Session session;
 
 
   boost::taus88 rng;
   boost::taus88 rng;
   boost::random::uniform_int_distribution<int> distribution;
   boost::random::uniform_int_distribution<int> distribution;
 
 
 #ifndef BENCHMARK_USE_POSTGRES
 #ifndef BENCHMARK_USE_POSTGRES
-  DbStructNoTransaction() : connection("hello_world", "benchmarkdbuser", "benchmarkdbpass", "INSERT_DB_HOST_HERE", 3306),
+  DbStruct() : connection("hello_world", "benchmarkdbuser", "benchmarkdbpass", "INSERT_DB_HOST_HERE", 3306),
 #else
 #else
-  DbStructNoTransaction() : connection("host=INSERT_DB_HOST_HERE port=5432 user=benchmarkdbuser password=benchmarkdbpass dbname=hello_world"),
+  DbStruct() : connection("host=INSERT_DB_HOST_HERE port=5432 user=benchmarkdbuser password=benchmarkdbpass dbname=hello_world"),
 #endif
 #endif
       rng(clock()),
       rng(clock()),
       distribution(1, 10000) {
       distribution(1, 10000) {
@@ -155,9 +136,11 @@ struct DbStructNoTransaction {
   }
   }
 };
 };
 
 
-class DbResource : public Wt::WResource {
-private:
+namespace {
   boost::thread_specific_ptr<DbStruct> dbStruct_;
   boost::thread_specific_ptr<DbStruct> dbStruct_;
+}
+
+class DbResource : public Wt::WResource {
 public:
 public:
   virtual void handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) {
   virtual void handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) {
     response.setMimeType("application/json");
     response.setMimeType("application/json");
@@ -165,13 +148,11 @@ public:
 
 
     DbStruct* db = dbStruct_.get();
     DbStruct* db = dbStruct_.get();
     if (!db) {
     if (!db) {
-      std::lock_guard<std::mutex> lock(mtx);
-      if (!db) {
-        db = new DbStruct();
-        dbStruct_.reset(db);
-      }
+      db = new DbStruct();
+      dbStruct_.reset(db);
     }
     }
 
 
+    Wt::Dbo::Transaction transaction(db->session);
     Wt::Dbo::ptr<World> entry = db->session.load<World>(db->rand());
     Wt::Dbo::ptr<World> entry = db->session.load<World>(db->rand());
     
     
     Wt::Dbo::JsonSerializer writer(response.out());
     Wt::Dbo::JsonSerializer writer(response.out());
@@ -180,8 +161,6 @@ public:
 };
 };
 
 
 class QueriesResource : public Wt::WResource {
 class QueriesResource : public Wt::WResource {
-private:
-  boost::thread_specific_ptr<DbStruct> dbStruct_;
 public:
 public:
   virtual void handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) {
   virtual void handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) {
     int n;
     int n;
@@ -200,13 +179,11 @@ public:
 
 
     DbStruct* db = dbStruct_.get();
     DbStruct* db = dbStruct_.get();
     if (!db) {
     if (!db) {
-      std::lock_guard<std::mutex> lock(mtx);
-      if (!db) {
-        db = new DbStruct();
-        dbStruct_.reset(db);
-      }
+      db = new DbStruct();
+      dbStruct_.reset(db);
     }
     }
 
 
+    Wt::Dbo::Transaction transaction(db->session);
     std::vector<Wt::Dbo::ptr<World> > results;
     std::vector<Wt::Dbo::ptr<World> > results;
     results.reserve(n);
     results.reserve(n);
     for (int i = 0; i < n; ++i) {
     for (int i = 0; i < n; ++i) {
@@ -250,7 +227,7 @@ public:
 
 
   virtual void resolveString(const std::string& varName, const std::vector<Wt::WString>& vars, std::ostream& result) {
   virtual void resolveString(const std::string& varName, const std::vector<Wt::WString>& vars, std::ostream& result) {
     if (varName == "id")
     if (varName == "id")
-      format(result, Wt::WString::fromUTF8(boost::lexical_cast<std::string>(it_->id())), Wt::XHTMLUnsafeText);
+      result << it_->id();
     else if (varName == "message")
     else if (varName == "message")
       format(result, Wt::WString::fromUTF8((*it_)->message));
       format(result, Wt::WString::fromUTF8((*it_)->message));
     else
     else
@@ -259,8 +236,6 @@ public:
 };
 };
 
 
 class FortuneResource : public Wt::WResource {
 class FortuneResource : public Wt::WResource {
-private:
-  boost::thread_specific_ptr<DbStruct> dbStruct_;
 public:
 public:
   virtual void handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) {
   virtual void handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) {
     response.setMimeType("text/html; charset=utf-8");
     response.setMimeType("text/html; charset=utf-8");
@@ -268,13 +243,11 @@ public:
 
 
     DbStruct* db = dbStruct_.get();
     DbStruct* db = dbStruct_.get();
     if (!db) {
     if (!db) {
-      std::lock_guard<std::mutex> lock(mtx);
-      if (!db) {
-        db = new DbStruct();
-        dbStruct_.reset(db);
-      }
+      db = new DbStruct();
+      dbStruct_.reset(db);
     }
     }
 
 
+    Wt::Dbo::Transaction transaction(db->session);
     Fortunes fortunes = db->session.find<Fortune>();
     Fortunes fortunes = db->session.find<Fortune>();
     VFortunes vFortunes;
     VFortunes vFortunes;
     for (Fortunes::const_iterator i = fortunes.begin(); i != fortunes.end(); ++i)
     for (Fortunes::const_iterator i = fortunes.begin(); i != fortunes.end(); ++i)
@@ -293,8 +266,6 @@ public:
 };
 };
 
 
 class UpdateResource : public Wt::WResource {
 class UpdateResource : public Wt::WResource {
-private:
-  boost::thread_specific_ptr<DbStructNoTransaction> dbStruct_;
 public:
 public:
   virtual void handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) {
   virtual void handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) {
     int n;
     int n;
@@ -311,13 +282,10 @@ public:
     response.setMimeType("application/json");
     response.setMimeType("application/json");
     response.addHeader("Server", "Wt");
     response.addHeader("Server", "Wt");
 
 
-    DbStructNoTransaction* db = dbStruct_.get();
+    DbStruct* db = dbStruct_.get();
     if (!db) {
     if (!db) {
-      std::lock_guard<std::mutex> lock(mtx);
-      if (!db) {
-        db = new DbStructNoTransaction();
-        dbStruct_.reset(db);
-      }
+      db = new DbStruct();
+      dbStruct_.reset(db);
     }
     }
 
 
     std::vector<Wt::Dbo::ptr<World> > results;
     std::vector<Wt::Dbo::ptr<World> > results;

+ 2 - 2
frameworks/Java/spring/README.md

@@ -61,8 +61,8 @@ Check out [SampleApplication, the main Application file](src/main/java/com/teche
 ## Infrastructure Software Versions
 ## Infrastructure Software Versions
 The tests were run with:
 The tests were run with:
 
 
-* [Spring 4.1.3.RELEASE](http://projects.spring.io/spring-framework/)
-* [Spring Boot 1.2.0.RELEASE](http://projects.spring.io/spring-boot/)
+* [Spring 4.1.4.RELEASE](http://projects.spring.io/spring-framework/)
+* [Spring Boot 1.2.1.RELEASE](http://projects.spring.io/spring-boot/)
 * [Spring Data JPA 1.7.1.RELEASE](http://projects.spring.io/spring-data-jpa/)
 * [Spring Data JPA 1.7.1.RELEASE](http://projects.spring.io/spring-data-jpa/)
 * [Java OpenJDK 1.7.0_09](http://openjdk.java.net/)
 * [Java OpenJDK 1.7.0_09](http://openjdk.java.net/)
 * [Undertow 1.1.1.Final](http://undertow.io/)
 * [Undertow 1.1.1.Final](http://undertow.io/)

+ 1 - 1
frameworks/Java/spring/pom.xml

@@ -8,7 +8,7 @@
     <parent>
     <parent>
         <groupId>org.springframework.boot</groupId>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
         <artifactId>spring-boot-starter-parent</artifactId>
-        <version>1.2.0.RELEASE</version>
+        <version>1.2.1.RELEASE</version>
     </parent>
     </parent>
 
 
     <groupId>com.techempower</groupId>
     <groupId>com.techempower</groupId>

+ 26 - 0
frameworks/Java/spring/src/main/java/com/techempower/spring/SampleApplication.java

@@ -1,9 +1,16 @@
 package com.techempower.spring;
 package com.techempower.spring;
 
 
+import io.undertow.Undertow;
+import io.undertow.UndertowOptions;
+import org.xnio.Options;
+
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
 import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
 import org.springframework.boot.builder.SpringApplicationBuilder;
 import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.context.embedded.undertow.UndertowBuilderCustomizer;
+import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
 import org.springframework.boot.context.web.SpringBootServletInitializer;
 import org.springframework.boot.context.web.SpringBootServletInitializer;
+import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 
 
@@ -21,4 +28,23 @@ public class SampleApplication extends SpringBootServletInitializer {
 		new SpringApplicationBuilder(SampleApplication.class).run(args);
 		new SpringApplicationBuilder(SampleApplication.class).run(args);
 	}
 	}
 
 
+	@Bean
+	public UndertowEmbeddedServletContainerFactory embeddedServletContainerFactory() {
+		UndertowEmbeddedServletContainerFactory factory = new UndertowEmbeddedServletContainerFactory();
+		factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {
+
+			@Override
+			public void customize(Undertow.Builder builder) {
+				builder.setBufferSize(1024 * 16)
+						.setIoThreads(Runtime.getRuntime().availableProcessors() * 2)
+						.setSocketOption(Options.BACKLOG, 10000)
+						.setServerOption(UndertowOptions.ALWAYS_SET_KEEP_ALIVE, false)
+						.setServerOption(UndertowOptions.ALWAYS_SET_DATE, true)
+						.setWorkerThreads(200);
+			}
+
+		});
+		return factory;
+	}
+
 }
 }

+ 1 - 1
frameworks/Python/bottle/setup_nginxuwsgi.sh

@@ -3,4 +3,4 @@
 sed -i 's|include .*/conf/uwsgi_params;|include '"${NGINX_HOME}"'/conf/uwsgi_params;|g' nginx.conf
 sed -i 's|include .*/conf/uwsgi_params;|include '"${NGINX_HOME}"'/conf/uwsgi_params;|g' nginx.conf
 
 
 ${NGINX_HOME}/sbin/nginx -c ${TROOT}/nginx.conf
 ${NGINX_HOME}/sbin/nginx -c ${TROOT}/nginx.conf
-${PY2_ROOT}/bin/uwsgi -d ${ERR} --ini ${TROOT}/uwsgi.ini --processes ${MAX_THREADS} --wsgi app:app
+${PY2_ROOT}/bin/uwsgi --ini ${TROOT}/uwsgi.ini --processes ${MAX_THREADS} --wsgi app:app &

+ 1 - 1
frameworks/Python/flask/setup_nginxuwsgi.sh

@@ -3,4 +3,4 @@
 sed -i 's|include .*/conf/uwsgi_params;|include '"${NGINX_HOME}"'/conf/uwsgi_params;|g' nginx.conf
 sed -i 's|include .*/conf/uwsgi_params;|include '"${NGINX_HOME}"'/conf/uwsgi_params;|g' nginx.conf
 
 
 $NGINX_HOME/sbin/nginx -c $TROOT/nginx.conf
 $NGINX_HOME/sbin/nginx -c $TROOT/nginx.conf
-${PY2_ROOT}/bin/uwsgi -d ${ERR} --ini ${TROOT}/uwsgi.ini --processes ${MAX_THREADS} --wsgi app:app
+${PY2_ROOT}/bin/uwsgi --ini ${TROOT}/uwsgi.ini --processes ${MAX_THREADS} --wsgi app:app &

+ 1 - 1
frameworks/Python/uwsgi/setup_nginx.sh

@@ -3,4 +3,4 @@
 sed -i 's|include .*/conf/uwsgi_params;|include '"${NGINX_HOME}"'/conf/uwsgi_params;|g' nginx.conf
 sed -i 's|include .*/conf/uwsgi_params;|include '"${NGINX_HOME}"'/conf/uwsgi_params;|g' nginx.conf
 
 
 $NGINX_HOME/sbin/nginx -c ${TROOT}/nginx.conf
 $NGINX_HOME/sbin/nginx -c ${TROOT}/nginx.conf
-$PY2_ROOT/bin/uwsgi -d ${ERR} --ini uwsgi.ini --processes ${MAX_THREADS} --gevent 1000 --wsgi hello
+$PY2_ROOT/bin/uwsgi --ini uwsgi.ini --processes ${MAX_THREADS} --gevent 1000 --wsgi hello &

+ 1 - 1
frameworks/Python/wsgi/setup_nginxuwsgi.sh

@@ -3,4 +3,4 @@
 sed -i 's|include .*/conf/uwsgi_params;|include '"${NGINX_HOME}"'/conf/uwsgi_params;|g' nginx.conf
 sed -i 's|include .*/conf/uwsgi_params;|include '"${NGINX_HOME}"'/conf/uwsgi_params;|g' nginx.conf
 
 
 $NGINX_HOME/sbin/nginx -c $TROOT/nginx.conf
 $NGINX_HOME/sbin/nginx -c $TROOT/nginx.conf
-$PY2_ROOT/bin/uwsgi -d ${ERR} --ini uwsgi.ini --processes ${MAX_THREADS} --wsgi hello:app
+$PY2_ROOT/bin/uwsgi --ini uwsgi.ini --processes ${MAX_THREADS} --wsgi hello:app &

+ 1 - 1
frameworks/Scala/play2-scala/benchmark_config

@@ -98,7 +98,7 @@
         "webserver": "None",
         "webserver": "None",
         "os": "Linux",
         "os": "Linux",
         "database_os": "Linux",
         "database_os": "Linux",
-        "display_name": "play2-scala-rmongo",
+        "display_name": "play2-scala-mongodb",
         "notes": "Uses Reactive Mongo",
         "notes": "Uses Reactive Mongo",
         "versus": "netty"
         "versus": "netty"
       }
       }

+ 26 - 8
toolset/setup/linux/database.sh

@@ -30,6 +30,14 @@ export TFB_DISTRIB_RELEASE=$DISTRIB_RELEASE
 export TFB_DISTRIB_CODENAME=$DISTRIB_CODENAME
 export TFB_DISTRIB_CODENAME=$DISTRIB_CODENAME
 export TFB_DISTRIB_DESCRIPTION=$DISTRIB_DESCRIPTION
 export TFB_DISTRIB_DESCRIPTION=$DISTRIB_DESCRIPTION
 
 
+##############################
+# check environment
+##############################
+
+# verify that $TFB_DBHOST is set
+echo "TFB_DBHOST: $TFB_DBHOST"
+[ -z "$TFB_DBHOST" ] && echo "ERROR: TFB_DBHOST is not set!"
+
 ##############################
 ##############################
 # Prerequisites
 # Prerequisites
 ##############################
 ##############################
@@ -170,24 +178,34 @@ sudo ln -s /opt/apache-cassandra-$CASS_V /opt/cassandra
 
 
 rm -rf /ssd/cassandra /ssd/log/cassandra
 rm -rf /ssd/cassandra /ssd/log/cassandra
 mkdir -p /ssd/cassandra /ssd/log/cassandra
 mkdir -p /ssd/cassandra /ssd/log/cassandra
-sudo chown -R cassandra:cassandra /ssd/cassandra
+sudo chown -R cassandra:cassandra /ssd/cassandra /ssd/log/cassandra
+
+cp cassandra/cassandra.yaml cassandra/cassandra.yaml.mod
+cat <<EOF > cassandra/cass_conf_replace.sed
+s/- seeds: "\([^"]*\)"/- seeds: "$TFB_DBHOST"/
+s/listen_address: \(.*\)/listen_address: $TFB_DBHOST/
+s/rpc_address: \(.*\)/rpc_address: $TFB_DBHOST/
+EOF
+sed -i -f cassandra/cass_conf_replace.sed cassandra/cassandra.yaml.mod
+
 sudo cp -f cassandra/cassandra.init /etc/init.d/cassandra
 sudo cp -f cassandra/cassandra.init /etc/init.d/cassandra
 sudo cp -f cassandra/cassandra.init.env /etc/default/cassandra
 sudo cp -f cassandra/cassandra.init.env /etc/default/cassandra
-sudo cp -f cassandra/cassandra.yaml /opt/apache-cassandra-$CASS_V/conf
+sudo cp -f cassandra/cassandra.yaml.mod /opt/apache-cassandra-$CASS_V/conf/cassandra.yaml
 sudo cp -f cassandra/log4j-server.properties /opt/apache-cassandra-$CASS_V/conf
 sudo cp -f cassandra/log4j-server.properties /opt/apache-cassandra-$CASS_V/conf
+
 sudo update-rc.d cassandra defaults
 sudo update-rc.d cassandra defaults
-sudo service cassandra start
+sudo service cassandra restart
 
 
 for i in {1..45}; do
 for i in {1..45}; do
-  nc -z localhost 9160 && break || sleep 1;
+  nc -z $TFB_DBHOST 9160 && break || sleep 1;
   echo "Waiting for Cassandra ($i/45}"
   echo "Waiting for Cassandra ($i/45}"
 done
 done
-nc -z localhost 9160
+nc -z $TFB_DBHOST 9160
 if [ $? -eq 0 ]; then
 if [ $? -eq 0 ]; then
-  cat cassandra/cleanup-keyspace.cql | /opt/apache-cassandra-$CASS_V/bin/cqlsh 127.0.0.1
+  cat cassandra/cleanup-keyspace.cql | /opt/apache-cassandra-$CASS_V/bin/cqlsh $TFB_DBHOST
   python cassandra/db-data-gen.py > cassandra/tfb-data.cql
   python cassandra/db-data-gen.py > cassandra/tfb-data.cql
-  /opt/apache-cassandra-$CASS_V/bin/cqlsh -f cassandra/create-keyspace.cql 127.0.0.1
-  /opt/apache-cassandra-$CASS_V/bin/cqlsh -f cassandra/tfb-data.cql 127.0.0.1
+  /opt/apache-cassandra-$CASS_V/bin/cqlsh -f cassandra/create-keyspace.cql $TFB_DBHOST
+  /opt/apache-cassandra-$CASS_V/bin/cqlsh -f cassandra/tfb-data.cql $TFB_DBHOST
 else
 else
   >&2 echo "Cassandra did not start, skipping"
   >&2 echo "Cassandra did not start, skipping"
 fi
 fi

+ 9 - 1
toolset/setup/linux/installer.py

@@ -19,6 +19,14 @@ class Installer:
     linux_install_root = self.fwroot + "/toolset/setup/linux"
     linux_install_root = self.fwroot + "/toolset/setup/linux"
     imode = self.benchmarker.install
     imode = self.benchmarker.install
 
 
+    script_vars = {
+      'TFB_DBHOST': self.benchmarker.database_host
+    }
+    l=[]
+    for k,v in script_vars.iteritems():
+      l.append("export %s=%s" % (k,v))
+    script_vars_str = "\n".join(l) + "\n\n"
+
     if imode == 'all' or imode == 'server':
     if imode == 'all' or imode == 'server':
       self.__install_server_software()
       self.__install_server_software()
 
 
@@ -30,7 +38,7 @@ class Installer:
         p = subprocess.Popen(self.benchmarker.database_ssh_string.split(" ") +
         p = subprocess.Popen(self.benchmarker.database_ssh_string.split(" ") +
                              ["bash"], stdin=subprocess.PIPE)
                              ["bash"], stdin=subprocess.PIPE)
         remote_script = myfile.read()
         remote_script = myfile.read()
-        p.communicate(remote_script)
+        p.communicate(script_vars_str + remote_script)
         returncode = p.returncode
         returncode = p.returncode
         if returncode != 0:
         if returncode != 0:
           self.__install_error("status code %s running subprocess '%s'." % (returncode, self.benchmarker.database_ssh_string))
           self.__install_error("status code %s running subprocess '%s'." % (returncode, self.benchmarker.database_ssh_string))

+ 4 - 4
toolset/setup/linux/languages/go.sh

@@ -1,9 +1,9 @@
 #!/bin/bash
 #!/bin/bash
 
 
-RETCODE=$(fw_exists ${IROOT}/go1.3.installed)
+RETCODE=$(fw_exists ${IROOT}/go1.4.2.installed)
 [ ! "$RETCODE" == 0 ] || { return 0; }
 [ ! "$RETCODE" == 0 ] || { return 0; }
 
 
-fw_get https://storage.googleapis.com/golang/go1.3.linux-amd64.tar.gz
-fw_untar go1.3.linux-amd64.tar.gz
+fw_get https://storage.googleapis.com/golang/go1.4.2.linux-amd64.tar.gz
+fw_untar go1.4.2.linux-amd64.tar.gz
 
 
-touch ${IROOT}/go1.3.installed
+touch ${IROOT}/go1.4.2.installed