Browse Source

merge upstream

Sergey Zavadski 11 years ago
parent
commit
e974bb8a81
100 changed files with 873 additions and 443 deletions
  1. 1 0
      HttpListener/install.sh
  2. 1 0
      README.md
  3. 3 0
      WeberFramework/install.sh
  4. 3 0
      activeweb/install.sh
  5. 3 0
      aspnet-stripped/install.sh
  6. 3 0
      aspnet/install.sh
  7. 4 2
      beego/benchmark_config
  8. 3 0
      beego/install.sh
  9. 55 0
      beego/src/hello/hello.go
  10. 1 1
      bottle/app.py
  11. 1 1
      bottle/benchmark_config
  12. 11 0
      bottle/gunicorn_conf.py
  13. 3 0
      bottle/install.sh
  14. 2 9
      bottle/setup.py
  15. 2 9
      bottle/setup_py3.py
  16. 3 0
      cake/install.sh
  17. 3 0
      compojure/install.sh
  18. 5 0
      config/benchmark_profile
  19. 2 2
      config/requirements-pypy.txt
  20. 1 0
      config/requirements.txt
  21. 3 0
      cowboy/install.sh
  22. 2 0
      cpoll_cppsp/install.sh
  23. 9 4
      cpoll_cppsp/www/db
  24. 9 4
      cpoll_cppsp/www/db_pg_async
  25. 9 4
      cpoll_cppsp/www/db_pg_threadpool
  26. 3 0
      curacao/install.sh
  27. 3 0
      dancer/install.sh
  28. 3 0
      dart-start/install.sh
  29. 3 0
      dart-stream/install.sh
  30. 3 0
      dart/install.sh
  31. 3 0
      django/install.sh
  32. 3 0
      dropwizard-mongodb/install.sh
  33. 3 0
      dropwizard/benchmark_config
  34. 10 26
      dropwizard/hello-world.yml
  35. 3 0
      dropwizard/install.sh
  36. 20 10
      dropwizard/pom.xml
  37. 14 10
      dropwizard/setup.py
  38. 15 5
      dropwizard/source_code
  39. 0 25
      dropwizard/src/main/java/com/example/helloworld/HelloWorldConfiguration.java
  40. 34 37
      dropwizard/src/main/java/com/example/helloworld/HelloWorldService.java
  41. 20 0
      dropwizard/src/main/java/com/example/helloworld/config/HelloWorldConfiguration.java
  42. 0 36
      dropwizard/src/main/java/com/example/helloworld/core/World.java
  43. 18 0
      dropwizard/src/main/java/com/example/helloworld/db/FortuneDAO.java
  44. 14 15
      dropwizard/src/main/java/com/example/helloworld/db/WorldDAO.java
  45. 35 0
      dropwizard/src/main/java/com/example/helloworld/db/model/Fortune.java
  46. 29 0
      dropwizard/src/main/java/com/example/helloworld/db/model/World.java
  47. 37 0
      dropwizard/src/main/java/com/example/helloworld/resources/FortuneResource.java
  48. 6 18
      dropwizard/src/main/java/com/example/helloworld/resources/JsonResource.java
  49. 16 0
      dropwizard/src/main/java/com/example/helloworld/resources/TextResource.java
  50. 47 28
      dropwizard/src/main/java/com/example/helloworld/resources/WorldResource.java
  51. 17 0
      dropwizard/src/main/java/com/example/helloworld/resources/api/HelloMessage.java
  52. 23 0
      dropwizard/src/main/java/com/example/helloworld/resources/views/FortuneView.java
  53. 14 0
      dropwizard/src/main/resources/fortunes.mustache
  54. 3 0
      elli/install.sh
  55. 3 0
      evhttp-sharp/install.sh
  56. 3 0
      express/install.sh
  57. 20 0
      falcon/gunicorn_conf.py
  58. 3 0
      falcon/install.sh
  59. 8 7
      falcon/setup.py
  60. 2 6
      falcon/setup_py3.py
  61. 12 10
      falcon/setup_pypy.py
  62. 3 0
      falcore/install.sh
  63. 2 0
      finagle/install.sh
  64. 28 16
      flask/app.py
  65. 7 7
      flask/benchmark_config
  66. 3 0
      flask/install.sh
  67. 1 0
      flask/requirements.txt
  68. 28 14
      flask/setup.py
  69. 24 9
      flask/setup_py3.py
  70. 1 1
      flask/setup_pypy.py
  71. 3 0
      gemini/install.sh
  72. 3 0
      go/install.sh
  73. 3 0
      grails/install.sh
  74. 3 0
      grizzly-bm/install.sh
  75. 3 0
      grizzly-jersey/install.sh
  76. 3 0
      hapi/install.sh
  77. 3 0
      hhvm/install.sh
  78. 2 0
      http-kit/install.sh
  79. 3 0
      jester/install.sh
  80. 3 0
      jetty-servlet/install.sh
  81. 3 0
      kelp/install.sh
  82. 3 0
      lapis/install.sh
  83. 2 0
      lift-stateless/install.sh
  84. 3 0
      luminus/install.sh
  85. 3 0
      mojolicious/install.sh
  86. 3 0
      nancy/install.sh
  87. 3 0
      nawak/install.sh
  88. 2 2
      netty/README.md
  89. 3 0
      netty/install.sh
  90. 5 4
      netty/pom.xml
  91. 57 66
      netty/src/main/java/hello/HelloServerHandler.java
  92. 9 7
      netty/src/main/java/hello/HelloServerInitializer.java
  93. 33 39
      netty/src/main/java/hello/HelloWebServer.java
  94. 9 9
      netty/src/main/java/hello/Message.java
  95. 3 0
      ninja-resin/install.sh
  96. 3 0
      ninja-standalone/install.sh
  97. 3 0
      nodejs/install.sh
  98. 2 0
      onion/install.sh
  99. 3 0
      openresty/install.sh
  100. 3 0
      php-codeigniter/install.sh

+ 1 - 0
HttpListener/install.sh

@@ -0,0 +1 @@
+#!/bin/bash

+ 1 - 0
README.md

@@ -25,6 +25,7 @@ $ sudo apt-get install openssh-server
 * If Ubuntu is already installed, run the following command and follow the prompts.
 ```bash
 $ sudo adduser tfb
+$ sudo usermod -a -G sudo tfb
 ```
 * Log in as `tfb`
 * Fully update **NOTE**: If you update the kernel (linux-firmware), it is generally a good idea to reboot aftewards.

+ 3 - 0
WeberFramework/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends weber elixir

+ 3 - 0
activeweb/install.sh

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

+ 3 - 0
aspnet-stripped/install.sh

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

+ 3 - 0
aspnet/install.sh

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

+ 4 - 2
beego/benchmark_config

@@ -4,13 +4,15 @@
     "default": {
       "setup_file": "setup",
       "json_url": "/json",
+      "db_url": "/db",
+      "plaintext_url": "/plaintext",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Micro",
-      "database": "None",
+      "database": "MySQL",
       "framework": "beego",
       "language": "Go",
-      "orm": "Raw",
+      "orm": "beego ORM",
       "platform": "Go",
       "webserver": "None",
       "os": "Linux",

+ 3 - 0
beego/install.sh

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

+ 55 - 0
beego/src/hello/hello.go

@@ -1,14 +1,38 @@
 package main
 
 import (
+	"log"
+	"math/rand"
 	"github.com/astaxie/beego"
+	"github.com/astaxie/beego/orm"
+
+	_ "github.com/go-sql-driver/mysql"
 	//"runtime"
 )
 
+const (
+	// Database
+	connectionString   = "benchmarkdbuser:benchmarkdbpass@tcp(localhost:3306)/hello_world"
+	worldRowCount      = 10000
+	macIdleConnection  = 30
+	maxConnectionCount = 256
+
+	helloWorldString = "Hello, World!"
+)
+
+var (
+	helloWorldBytes = []byte(helloWorldString)
+)
+
 type MessageStruct struct {
 	Message string `json:"message"`
 }
 
+type World struct {
+	Id           uint16 `orm:"pk" json:"id"`
+	RandomNumber uint16 `orm:"column(randomNumber)" json:"randomNumber"`
+}
+
 type JsonController struct {
 	beego.Controller
 }
@@ -19,10 +43,41 @@ func (this *JsonController) Get() {
 	this.ServeJson()
 }
 
+type PlaintextController struct {
+	beego.Controller
+}
+
+func (this *PlaintextController) Get() {
+	this.Ctx.Output.Header("Content-Type", "text/plain")
+	this.Ctx.Output.Body(helloWorldBytes)
+}
+
+type DBController struct {
+	beego.Controller
+}
+
+func (this *DBController) Get() {
+	o := orm.NewOrm()
+	w := World{Id: uint16(rand.Intn(worldRowCount) + 1)}
+	err := o.Read(&w)
+	if err != nil {
+		log.Fatalf("Error read world row: %s", err.Error())
+	}
+	this.Data["json"] = &w
+	this.ServeJson()
+}
+
 func main() {
 	//don't need this set, beego default set it
 	//runtime.GOMAXPROCS(runtime.NumCPU())
 	beego.RunMode = "prod"
 	beego.Router("/json", &JsonController{})
+	beego.Router("/db", &DBController{})
+	beego.Router("/plaintext", &PlaintextController{})
 	beego.Run()
 }
+
+func init() {
+	orm.RegisterModel(new(World))
+	orm.RegisterDataBase("default", "mysql", connectionString, macIdleConnection, maxConnectionCount)
+}

+ 1 - 1
bottle/app.py

@@ -13,7 +13,7 @@ except ImportError:
     import json
 
 app = Bottle()
-app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://benchmarkdbuser:benchmarkdbpass@DBHOSTNAME:3306/hello_world?charset=utf8'
+app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://benchmarkdbuser:benchmarkdbpass@localhost:3306/hello_world?charset=utf8'
 Base = declarative_base()
 db_engine = create_engine(app.config['SQLALCHEMY_DATABASE_URI'])
 plugin = sqlalchemy.Plugin(db_engine, keyword='db', )

+ 1 - 1
bottle/benchmark_config

@@ -44,7 +44,7 @@
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "bottle-py3",
-      "notes": "CPython 3.3",
+      "notes": "CPython 3.4",
       "versus": "wsgi"
     },
     "pypy": {

+ 11 - 0
bottle/gunicorn_conf.py

@@ -0,0 +1,11 @@
+import multiprocessing
+
+workers = multiprocessing.cpu_count() * 3
+bind = "0.0.0.0:8080"
+worker_class = "meinheld.gmeinheld.MeinheldWorker"
+keepalive = 120
+
+def post_fork(server, worker):
+    # Disalbe access log
+    import meinheld.server
+    meinheld.server.set_access_logger(None)

+ 3 - 0
bottle/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends python2 python3 pypy

+ 2 - 9
bottle/setup.py

@@ -1,10 +1,8 @@
 import subprocess
 import setup_util
-import multiprocessing
 import os
 
 bin_dir = os.path.expanduser('~/FrameworkBenchmarks/installs/py2/bin')
-NCPU = multiprocessing.cpu_count()
 
 proc = None
 
@@ -12,13 +10,8 @@ proc = None
 def start(args, logfile, errfile):
     global proc
     setup_util.replace_text("bottle/app.py", "DBHOSTNAME", args.database_host)
-    proc = subprocess.Popen([
-        bin_dir + "/gunicorn",
-        "app:app",
-        "-k", "meinheld.gmeinheld.MeinheldWorker",
-        "-b", "0.0.0.0:8080",
-        '-w', str(NCPU*3),
-        "--log-level=critical"],
+    proc = subprocess.Popen(
+        [bin_dir + "/gunicorn", "-c", "gunicorn_conf.py", "app:app"],
         cwd="bottle", stderr=errfile, stdout=logfile)
     return 0
 

+ 2 - 9
bottle/setup_py3.py

@@ -1,10 +1,8 @@
 import subprocess
 import setup_util
-import multiprocessing
 import os
 
 bin_dir = os.path.expanduser('~/FrameworkBenchmarks/installs/py3/bin')
-NCPU = multiprocessing.cpu_count()
 
 proc = None
 
@@ -12,13 +10,8 @@ proc = None
 def start(args, logfile, errfile):
     global proc
     setup_util.replace_text("bottle/app.py", "DBHOSTNAME", args.database_host)
-    proc = subprocess.Popen([
-        bin_dir + "/gunicorn",
-        "app:app",
-        "-k", "meinheld.gmeinheld.MeinheldWorker",
-        "-b", "0.0.0.0:8080",
-        '-w', str(NCPU*3),
-        "--log-level=critical"],
+    proc = subprocess.Popen(
+        [bin_dir + "/gunicorn", "-c", "gunicorn_conf.py", "app:app"],
         cwd="bottle", stderr=errfile, stdout=logfile)
     return 0
 

+ 3 - 0
cake/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends php nginx

+ 3 - 0
compojure/install.sh

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

+ 5 - 0
config/benchmark_profile

@@ -1,3 +1,5 @@
+# Start Benchmark profile
+
 export JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk-amd64
 export RESIN_HOME=~/FrameworkBenchmarks/installs/resin-4.0.36
 export GRAILS_HOME=~/FrameworkBenchmarks/installs/grails-2.4.2
@@ -28,3 +30,6 @@ export TFB_CLIENT_IDENTITY_FILE='/home/tfb/.ssh/id_rsa'
 export TFB_DATABASE_HOST='localhost'
 
 [ -e ~/.rvm ] && . ~/.rvm/scripts/'rvm'
+export LC_ALL='en_US.UTF-8'
+export NUMCPUS=`grep -c '^processor' /proc/cpuinfo`
+export MAKEFLAGS="-j $NUMCPUS -l $NUMCPUS"

+ 2 - 2
config/requirements-pypy.txt

@@ -9,7 +9,7 @@ PyMySQL==0.6.2
 # uwsgi is released too often to stick on single version.
 uwsgi
 
-gunicorn==19.0
+gunicorn==18.0
 meinheld==0.5.6
 
 # Tornado
@@ -33,4 +33,4 @@ bottle-sqlalchemy==0.4.1
 
 # Falcon
 # Cython==0.20.1
-# falcon==0.1.8
+falcon==0.1.8

+ 1 - 0
config/requirements.txt

@@ -1,3 +1,4 @@
+circus
 mysqlclient==1.3.1
 PyMySQL==0.6.2
 psycopg2==2.5.3

+ 3 - 0
cowboy/install.sh

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

+ 2 - 0
cpoll_cppsp/install.sh

@@ -0,0 +1,2 @@
+#!/bin/bash
+

+ 9 - 4
cpoll_cppsp/www/db

@@ -128,13 +128,18 @@ void efdCB(eventfd_t efdVal) {
 void waitCB(eventfd_t efdVal) {
 	this->doInit();
 }
-
-%>[<%
+%><%
+if (queries>1) {
+	%>[<%
+}
 for (int i=0;i<queries;i++){
 	if(i>0) output.write(',');
 	%>{"id":<%=items[i].id%>,"randomNumber":<%=items[i].rnd%>}<%
 }
-
+if (queries>1) {
+	%>]<%
+}
+%><%
 response->headers["Content-Type"]="application/json";
 response->headers["Server"]="cppsp/0.2";
-%>]
+%>

+ 9 - 4
cpoll_cppsp/www/db_pg_async

@@ -107,13 +107,18 @@ void evtIn(int) {
 	PQclear(res);
 	beginGetItems();
 }
-
-%>[<%
+%><%
+if(queries>1) {
+	%>[<%
+}
 for (int i=0;i<queries;i++){
 	if(i>0) output.write(',');
 	%>{"id":<%=items[i].id%>,"randomNumber":<%=items[i].rnd%>}<%
 }
-
+if(queries>1) {
+        %>]<%
+}
+%><%
 response->headers["Content-Type"]="application/json";
 response->headers["Server"]="cppsp/0.2";
-%>]
+%>

+ 9 - 4
cpoll_cppsp/www/db_pg_threadpool

@@ -94,13 +94,18 @@ void efdCB(eventfd_t efdVal) {
 void waitCB(eventfd_t efdVal) {
 	this->doInit();
 }
-
-%>[<%
+%><%
+if(queries>1) {
+	%>[<%
+}
 for (int i=0;i<queries;i++){
 	if(i>0) output.write(',');
 	%>{"id":<%=items[i].id%>,"randomNumber":<%=items[i].rnd%>}<%
 }
-
+if(queries>1) {
+        %>]<%
+}
+%><%
 response->headers["Content-Type"]="application/json";
 response->headers["Server"]="cppsp/0.2";
-%>]
+%>

+ 3 - 0
curacao/install.sh

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

+ 3 - 0
dancer/install.sh

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

+ 3 - 0
dart-start/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends dart nginx

+ 3 - 0
dart-stream/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends dart nginx

+ 3 - 0
dart/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends dart nginx

+ 3 - 0
django/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends python2 python3

+ 3 - 0
dropwizard-mongodb/install.sh

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

+ 3 - 0
dropwizard/benchmark_config

@@ -6,6 +6,9 @@
       "json_url": "/json",
       "db_url": "/db",
       "query_url": "/db?queries=",
+      "fortune_url": "/fortunes",
+      "update_url": "/db/update?queries=",
+      "plaintext_url": "/plaintext",
       "port": 9000,
       "approach": "Realistic",
       "classification": "Fullstack",

+ 10 - 26
dropwizard/hello-world.yml

@@ -1,12 +1,16 @@
-http:
-  port: 9000
+server:
+  type: simple
+  applicationContextPath: /
+  connector:
+    type: http
+    port: 9000
+    useServerHeader: true
 
   requestLog:
+    appenders: []
 
-    # Settings for logging to stdout.
-    console:
-      # If true, log requests to stdout.
-      enabled: false
+logging:
+  appenders: []
 
 database:
   # the name of your JDBC driver
@@ -28,9 +32,6 @@ database:
   # the maximum amount of time to wait on an empty pool before throwing an exception
   maxWaitForConnection: 1s
 
-  # the SQL query to run when validating a connection's liveness
-  validationQuery: "/* MyService Health Check */ SELECT 1"
-
   # the minimum number of connections to keep open
   minSize: 8
 
@@ -39,20 +40,3 @@ database:
 
   # whether or not idle connections should be validated
   checkConnectionWhileIdle: false
-
-  # how long a connection must be held before it can be validated
-  checkConnectionHealthWhenIdleFor: 10s
-
-  # the maximum lifetime of an idle connection
-  closeConnectionIfIdleFor: 1 minute
-
-logging:
-
-  # The default level of all loggers. Can be OFF, ERROR, WARN, INFO, DEBUG, TRACE, or ALL.
-  level: OFF
-
-  console:
-
-    # If true, write log statements to stdout.
-    enabled: false
-

+ 3 - 0
dropwizard/install.sh

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

+ 20 - 10
dropwizard/pom.xml

@@ -1,28 +1,38 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <groupId>com.xekm</groupId>
     <artifactId>hello-world</artifactId>
     <version>0.0.1-SNAPSHOT</version>
 
+    <properties>
+        <jdk.version>1.7</jdk.version>
+
+        <dropwizard.version>0.7.0</dropwizard.version>
+        <mysql-connector-java.version>5.1.30</mysql-connector-java.version>
+    </properties>
+
     <dependencies>
         <dependency>
-            <groupId>com.yammer.dropwizard</groupId>
+            <groupId>io.dropwizard</groupId>
             <artifactId>dropwizard-core</artifactId>
-            <version>0.6.2</version>
+            <version>${dropwizard.version}</version>
         </dependency>
         <dependency>
-            <groupId>com.yammer.dropwizard</groupId>
+            <groupId>io.dropwizard</groupId>
             <artifactId>dropwizard-hibernate</artifactId>
-            <version>0.6.2</version>
+            <version>${dropwizard.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.dropwizard</groupId>
+            <artifactId>dropwizard-views-mustache</artifactId>
+            <version>${dropwizard.version}</version>
         </dependency>
         <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
-            <version>5.1.6</version>
+            <version>${mysql-connector-java.version}</version>
         </dependency>
     </dependencies>
 
@@ -33,8 +43,8 @@
                 <artifactId>maven-compiler-plugin</artifactId>
                 <version>2.3.2</version>
                 <configuration>
-                    <source>1.7</source>
-                    <target>1.7</target>
+                    <source>${jdk.version}</source>
+                    <target>${jdk.version}</target>
                 </configuration>
             </plugin>
             <plugin>

+ 14 - 10
dropwizard/setup.py

@@ -1,25 +1,29 @@
 import subprocess
-import sys
 import setup_util
 from os.path import expanduser
 import os
 
 home = expanduser("~")
 
+
 def start(args, logfile, errfile):
-    setup_util.replace_text("dropwizard/hello-world.yml", "url: jdbc:mysql://.*/hello_world", "url: jdbc:mysql://" + args.database_host + ":3306/hello_world")
+    setup_util.replace_text("dropwizard/hello-world.yml", "url: jdbc:mysql://.*/hello_world",
+                            "url: jdbc:mysql://" + args.database_host + ":3306/hello_world")
 
     try:
         subprocess.check_call("mvn clean package;", shell=True, cwd="dropwizard", stderr=errfile, stdout=logfile)
-        subprocess.Popen("java -jar target/hello-world-0.0.1-SNAPSHOT.jar server hello-world.yml", shell=True, cwd="dropwizard", stderr=errfile, stdout=logfile)
+        subprocess.Popen("java -jar target/hello-world-0.0.1-SNAPSHOT.jar server hello-world.yml", shell=True,
+                         cwd="dropwizard", stderr=errfile, stdout=logfile)
         return 0
     except subprocess.CalledProcessError:
         return 1
+
+
 def stop(logfile, errfile):
-  p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
-  out, err = p.communicate()
-  for line in out.splitlines():
-    if 'hello-world' in line:
-      pid = int(line.split(None, 2)[1])
-      os.kill(pid, 15)
-  return 0
+    p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
+    out, err = p.communicate()
+    for line in out.splitlines():
+        if 'hello-world' in line:
+            pid = int(line.split(None, 2)[1])
+            os.kill(pid, 15)
+    return 0

+ 15 - 5
dropwizard/source_code

@@ -1,10 +1,20 @@
 ./dropwizard/src/main/java/com/example/helloworld/
+./dropwizard/src/main/java/com/example/helloworld/config
+./dropwizard/src/main/java/com/example/helloworld/config/HelloWorldConfiguration
 ./dropwizard/src/main/java/com/example/helloworld/db
+./dropwizard/src/main/java/com/example/helloworld/db/model
+./dropwizard/src/main/java/com/example/helloworld/db/model/Fortune
+./dropwizard/src/main/java/com/example/helloworld/db/model/World
+./dropwizard/src/main/java/com/example/helloworld/db/FortuneDAO.java
 ./dropwizard/src/main/java/com/example/helloworld/db/WorldDAO.java
-./dropwizard/src/main/java/com/example/helloworld/HelloWorldService.java
 ./dropwizard/src/main/java/com/example/helloworld/resources
-./dropwizard/src/main/java/com/example/helloworld/resources/WorldResource.java
+./dropwizard/src/main/java/com/example/helloworld/resources/api
+./dropwizard/src/main/java/com/example/helloworld/resources/api/HelloMessage
+./dropwizard/src/main/java/com/example/helloworld/resources/views
+./dropwizard/src/main/java/com/example/helloworld/resources/views/FortuneView
+./dropwizard/src/main/java/com/example/helloworld/resources/FortuneResource.java
 ./dropwizard/src/main/java/com/example/helloworld/resources/JsonResource.java
-./dropwizard/src/main/java/com/example/helloworld/core
-./dropwizard/src/main/java/com/example/helloworld/core/World.java
-./dropwizard/src/main/java/com/example/helloworld/HelloWorldConfiguration.java
+./dropwizard/src/main/java/com/example/helloworld/resources/TextResource.java
+./dropwizard/src/main/java/com/example/helloworld/resources/WorldResource.java
+./dropwizard/src/main/java/com/example/helloworld/HelloWorldService.java
+./dropwizard/src/main/resources/fortunes.mustache

+ 0 - 25
dropwizard/src/main/java/com/example/helloworld/HelloWorldConfiguration.java

@@ -1,25 +0,0 @@
-
-package com.example.helloworld;
-
-import javax.validation.Valid;
-import javax.validation.constraints.NotNull;
-
-import org.hibernate.validator.constraints.NotEmpty;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.yammer.dropwizard.config.Configuration;
-import com.yammer.dropwizard.db.DatabaseConfiguration;
-
-public class HelloWorldConfiguration
-    extends Configuration
-{
-  @Valid
-  @NotNull
-  @JsonProperty
-  private DatabaseConfiguration database    = new DatabaseConfiguration();
-
-  public DatabaseConfiguration getDatabaseConfiguration()
-  {
-    return database;
-  }
-}

+ 34 - 37
dropwizard/src/main/java/com/example/helloworld/HelloWorldService.java

@@ -1,48 +1,45 @@
-
 package com.example.helloworld;
 
-import com.example.helloworld.core.World;
+import com.example.helloworld.config.HelloWorldConfiguration;
+import com.example.helloworld.db.FortuneDAO;
+import com.example.helloworld.db.model.Fortune;
+import com.example.helloworld.db.model.World;
 import com.example.helloworld.db.WorldDAO;
+import com.example.helloworld.resources.FortuneResource;
 import com.example.helloworld.resources.JsonResource;
+import com.example.helloworld.resources.TextResource;
 import com.example.helloworld.resources.WorldResource;
-import com.yammer.dropwizard.Service;
-import com.yammer.dropwizard.config.Bootstrap;
-import com.yammer.dropwizard.config.Environment;
-import com.yammer.dropwizard.db.DatabaseConfiguration;
-import com.yammer.dropwizard.hibernate.HibernateBundle;
+import io.dropwizard.Application;
+import io.dropwizard.db.DataSourceFactory;
+import io.dropwizard.hibernate.HibernateBundle;
+import io.dropwizard.setup.Bootstrap;
+import io.dropwizard.setup.Environment;
+import io.dropwizard.views.ViewBundle;
 
-public class HelloWorldService
-    extends Service<HelloWorldConfiguration>
-{
-  private final HibernateBundle<HelloWorldConfiguration> hibernate = new HibernateBundle<HelloWorldConfiguration>(
-                                                                       World.class)
-                                                                   {
-                                                                     @Override
-                                                                     public DatabaseConfiguration getDatabaseConfiguration(
-                                                                         HelloWorldConfiguration configuration)
-                                                                     {
-                                                                       return configuration.getDatabaseConfiguration();
-                                                                     }
-                                                                   };
+public class HelloWorldService extends Application<HelloWorldConfiguration> {
 
-  public static void main(String[] args) throws Exception
-  {
-    new HelloWorldService().run(args);
-  }
+    private final HibernateBundle<HelloWorldConfiguration> hibernate = new HibernateBundle<HelloWorldConfiguration>(World.class, Fortune.class) {
+        @Override
+        public DataSourceFactory getDataSourceFactory(HelloWorldConfiguration configuration) {
+            return configuration.getDatabaseConfiguration();
+        }
+    };
 
-  @Override
-  public void initialize(Bootstrap<HelloWorldConfiguration> bootstrap)
-  {
-    bootstrap.setName("hello-world");
-    bootstrap.addBundle(hibernate);
-  }
+    public static void main(String[] args) throws Exception {
+        new HelloWorldService().run(args);
+    }
 
-  @Override
-  public void run(HelloWorldConfiguration config, Environment environment)
-  {
-    final WorldDAO dao = new WorldDAO(hibernate.getSessionFactory());
-    environment.addResource(new WorldResource(dao));
-    environment.addResource(new JsonResource());
-  }
+    @Override
+    public void initialize(Bootstrap<HelloWorldConfiguration> bootstrap) {
+        bootstrap.addBundle(hibernate);
+        bootstrap.addBundle(new ViewBundle());
+    }
 
+    @Override
+    public void run(HelloWorldConfiguration config, Environment environment) {
+        environment.jersey().register(new JsonResource()); // Test type 1: JSON serialization
+        environment.jersey().register(new WorldResource(new WorldDAO(hibernate.getSessionFactory()))); // Test types 2, 3 & 5: Single database query, Multiple database queries & Database updates
+        environment.jersey().register(new FortuneResource(new FortuneDAO(hibernate.getSessionFactory()))); // Test type 4: Fortunes
+        environment.jersey().register(new TextResource()); // Test type 6: Plaintext
+    }
 }

+ 20 - 0
dropwizard/src/main/java/com/example/helloworld/config/HelloWorldConfiguration.java

@@ -0,0 +1,20 @@
+package com.example.helloworld.config;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.dropwizard.Configuration;
+import io.dropwizard.db.DataSourceFactory;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+
+public class HelloWorldConfiguration extends Configuration {
+
+    @Valid
+    @NotNull
+    @JsonProperty
+    private DataSourceFactory database = new DataSourceFactory();
+
+    public DataSourceFactory getDatabaseConfiguration() {
+        return database;
+    }
+}

+ 0 - 36
dropwizard/src/main/java/com/example/helloworld/core/World.java

@@ -1,36 +0,0 @@
-
-package com.example.helloworld.core;
-
-import javax.persistence.*;
-
-@Entity
-@Table(name = "World")
-public class World
-{
-  @Id
-  @GeneratedValue(strategy = GenerationType.AUTO)
-  private long id;
-
-  @Column(name = "randomNumber", nullable = false)
-  private long randomNumber;
-
-  public long getId()
-  {
-    return id;
-  }
-
-  public void setId(long id)
-  {
-    this.id = id;
-  }
-
-  public long getRandomNumber()
-  {
-    return this.randomNumber;
-  }
-
-  public void setRandomNumber(long randomNumber)
-  {
-    this.randomNumber = randomNumber;
-  }
-}

+ 18 - 0
dropwizard/src/main/java/com/example/helloworld/db/FortuneDAO.java

@@ -0,0 +1,18 @@
+package com.example.helloworld.db;
+
+import com.example.helloworld.db.model.Fortune;
+import io.dropwizard.hibernate.AbstractDAO;
+import org.hibernate.SessionFactory;
+
+import java.util.List;
+
+public class FortuneDAO extends AbstractDAO<Fortune> {
+
+    public FortuneDAO(SessionFactory factory) {
+        super(factory);
+    }
+
+    public List<Fortune> list() {
+        return list(criteria());
+    }
+}

+ 14 - 15
dropwizard/src/main/java/com/example/helloworld/db/WorldDAO.java

@@ -1,22 +1,21 @@
-
 package com.example.helloworld.db;
 
+import com.example.helloworld.db.model.World;
+import com.google.common.base.Optional;
+import io.dropwizard.hibernate.AbstractDAO;
 import org.hibernate.SessionFactory;
 
-import com.example.helloworld.core.World;
-import com.google.common.base.Optional;
-import com.yammer.dropwizard.hibernate.AbstractDAO;
+public class WorldDAO extends AbstractDAO<World> {
+
+    public WorldDAO(SessionFactory factory) {
+        super(factory);
+    }
 
-public class WorldDAO
-    extends AbstractDAO<World>
-{
-  public WorldDAO(SessionFactory factory)
-  {
-    super(factory);
-  }
+    public Optional<World> findById(Long id) {
+        return Optional.fromNullable(get(id));
+    }
 
-  public Optional<World> findById(Long id)
-  {
-    return Optional.fromNullable(get(id));
-  }
+    public World update(World world) {
+        return persist(world);
+    }
 }

+ 35 - 0
dropwizard/src/main/java/com/example/helloworld/db/model/Fortune.java

@@ -0,0 +1,35 @@
+package com.example.helloworld.db.model;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "Fortune")
+public class Fortune implements Comparable<Fortune> {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private long id;
+
+    @Column(name = "message", nullable = false)
+    private String message;
+
+    @SuppressWarnings("unused")
+    public Fortune() {}
+
+    public Fortune(String message) {
+        this.message = message;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    @Override
+    public int compareTo(Fortune o) {
+        return message.compareTo(o.message);
+    }
+}

+ 29 - 0
dropwizard/src/main/java/com/example/helloworld/db/model/World.java

@@ -0,0 +1,29 @@
+package com.example.helloworld.db.model;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "World")
+public class World {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private long id;
+
+    @Column(name = "randomNumber", nullable = false)
+    private long randomNumber;
+
+    public World() {}
+
+    public long getId() {
+        return id;
+    }
+
+    public long getRandomNumber() {
+        return randomNumber;
+    }
+
+    public void setRandomNumber(long randomNumber) {
+        this.randomNumber = randomNumber;
+    }
+}

+ 37 - 0
dropwizard/src/main/java/com/example/helloworld/resources/FortuneResource.java

@@ -0,0 +1,37 @@
+package com.example.helloworld.resources;
+
+import com.example.helloworld.db.FortuneDAO;
+import com.example.helloworld.db.model.Fortune;
+import com.example.helloworld.resources.views.FortuneView;
+import com.google.common.collect.Lists;
+import io.dropwizard.hibernate.UnitOfWork;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import java.util.Collections;
+import java.util.List;
+
+@Path("/fortunes")
+@Produces(MediaType.TEXT_HTML + ";charset=UTF-8")
+public class FortuneResource {
+
+    private final FortuneDAO fortuneDAO;
+
+    public FortuneResource(FortuneDAO fortuneDAO) {
+        this.fortuneDAO = fortuneDAO;
+    }
+
+    @GET
+    @UnitOfWork
+    public FortuneView dbTest() {
+        final List<Fortune> fortunes = Lists.newArrayListWithExpectedSize(32);
+
+        fortunes.addAll(fortuneDAO.list());
+        fortunes.add(new Fortune("Additional fortune added at request time."));
+
+        Collections.sort(fortunes);
+        return new FortuneView(fortunes);
+    }
+}

+ 6 - 18
dropwizard/src/main/java/com/example/helloworld/resources/JsonResource.java

@@ -1,8 +1,6 @@
-
 package com.example.helloworld.resources;
 
-import java.util.HashMap;
-import java.util.Map;
+import com.example.helloworld.resources.api.HelloMessage;
 
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
@@ -11,20 +9,10 @@ import javax.ws.rs.core.MediaType;
 
 @Path("/json")
 @Produces(MediaType.APPLICATION_JSON)
-public class JsonResource
-{
-  // Response message class (copied from 'servlet' test)
-  public final static class HelloMessage {
-    public final String message;
-
-    public HelloMessage(String m) { message = m; }
-  }
-
-  public JsonResource() { }
+public class JsonResource {
 
-  @GET
-  public HelloMessage sayHello()
-  {
-    return new HelloMessage("Hello, World!");
-  }
+    @GET
+    public HelloMessage sayHello() {
+        return new HelloMessage("Hello, World!");
+    }
 }

+ 16 - 0
dropwizard/src/main/java/com/example/helloworld/resources/TextResource.java

@@ -0,0 +1,16 @@
+package com.example.helloworld.resources;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Path("/plaintext")
+@Produces(MediaType.TEXT_PLAIN)
+public class TextResource {
+
+    @GET
+    public String sayHello() {
+        return "Hello, World!";
+    }
+}

+ 47 - 28
dropwizard/src/main/java/com/example/helloworld/resources/WorldResource.java

@@ -1,41 +1,60 @@
 package com.example.helloworld.resources;
 
-import java.util.Random;
+import com.example.helloworld.db.WorldDAO;
+import com.example.helloworld.db.model.World;
+import com.google.common.base.Optional;
+import io.dropwizard.hibernate.UnitOfWork;
 
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
-
-import com.example.helloworld.core.World;
-import com.example.helloworld.db.WorldDAO;
-import com.google.common.base.Optional;
-import com.yammer.dropwizard.hibernate.UnitOfWork;
+import java.util.Random;
 
 @Path("/db")
 @Produces(MediaType.APPLICATION_JSON)
-public class WorldResource
-{
-  private WorldDAO worldDAO = null;
-
-  public WorldResource(WorldDAO worldDAO)
-  {
-    this.worldDAO = worldDAO;
-  }
-
-  @GET
-  @UnitOfWork
-  public World[] dbTest(@QueryParam("queries") Optional<Integer> queries)
-  {
-    final int totalQueries = queries.or(1);
-    final World[] worlds = new World[queries.or(1)];
-    final Random random = new Random(System.currentTimeMillis());
-
-    for (int i = 0; i < totalQueries; i++)
-    {
-      worlds[i] = this.worldDAO.findById((long)(random.nextInt(10000) + 1)).orNull();
+public class WorldResource {
+
+    private static final Random RANDOM = new Random();
+
+    private final WorldDAO worldDAO;
+
+    public WorldResource(WorldDAO worldDAO) {
+        this.worldDAO = worldDAO;
+    }
+
+    @GET
+    @UnitOfWork
+    public World[] dbTest(@QueryParam("queries") Optional<Integer> queries) {
+        final int totalQueries = queries.or(1); // TODO: Should be bound [1,500]
+        final World[] worlds = new World[totalQueries];
+
+        // TODO: Is parallelising this cheating?
+        for (int i = 0; i < totalQueries; i++) {
+            final long worldId = RANDOM.nextInt(10_000) + 1;
+            worlds[i] = worldDAO.findById(worldId).orNull();
+        }
+
+        return worlds;
+    }
+
+    @GET
+    @Path("/update")
+    @UnitOfWork
+    public World[] updateTest(@QueryParam("queries") Optional<Integer> queries) {
+        final int totalQueries = queries.or(1); // TODO: Should be bound [1,500]
+        final World[] worlds = new World[totalQueries];
+
+        // TODO: Is parallelising this cheating?
+        for (int i = 0; i < totalQueries; i++) {
+            final long worldId = RANDOM.nextInt(10_000) + 1;
+
+            final World world = worldDAO.findById(worldId).orNull();
+            world.setRandomNumber(RANDOM.nextInt(10_000) + 1);
+            worlds[i] = worldDAO.update(world);
+        }
+
+        return worlds;
     }
-    return worlds;
-  }
 }

+ 17 - 0
dropwizard/src/main/java/com/example/helloworld/resources/api/HelloMessage.java

@@ -0,0 +1,17 @@
+package com.example.helloworld.resources.api;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public final class HelloMessage {
+
+    @JsonProperty
+    private final String message;
+
+    public HelloMessage(String m) {
+        message = m;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+}

+ 23 - 0
dropwizard/src/main/java/com/example/helloworld/resources/views/FortuneView.java

@@ -0,0 +1,23 @@
+package com.example.helloworld.resources.views;
+
+import com.example.helloworld.db.model.Fortune;
+import io.dropwizard.views.View;
+
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+public class FortuneView extends View {
+
+    private final List<Fortune> fortunes;
+
+    public FortuneView(List<Fortune> fortunes) {
+        super("/fortunes.mustache", StandardCharsets.UTF_8);
+
+        this.fortunes = fortunes;
+    }
+
+    @SuppressWarnings("unused")
+    public List<Fortune> getFortunes() {
+        return fortunes;
+    }
+}

+ 14 - 0
dropwizard/src/main/resources/fortunes.mustache

@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Fortunes</title>
+    </head>
+    <body>
+        <table>
+            <tr><th>id</th><th>message</th></tr>
+{{#fortunes}}
+                <tr><td>{{id}}</td><td>{{message}}</td></tr>
+{{/fortunes}}
+        </table>
+    </body>
+</html>

+ 3 - 0
elli/install.sh

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

+ 3 - 0
evhttp-sharp/install.sh

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

+ 3 - 0
express/install.sh

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

+ 20 - 0
falcon/gunicorn_conf.py

@@ -0,0 +1,20 @@
+import multiprocessing
+import sys
+
+_is_pypy = hasattr(sys, 'pypy_version_info')
+
+# falcon only implements json and plain. Not wait DB.
+workers = multiprocessing.cpu_count()
+bind = "0.0.0.0:8080"
+keepalive = 120
+
+if _is_pypy:
+    worker_class = "tornado"
+else:
+    worker_class = "meinheld.gmeinheld.MeinheldWorker"
+
+    def post_fork(server, worker):
+        # Disalbe access log
+        import meinheld.server
+        meinheld.server.set_access_logger(None)
+

+ 3 - 0
falcon/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends python2 python3 pypy

+ 8 - 7
falcon/setup.py

@@ -1,9 +1,7 @@
 import subprocess
-import multiprocessing
 import os
 
 bin_dir = os.path.expanduser('~/FrameworkBenchmarks/installs/py2/bin')
-NCPU = multiprocessing.cpu_count()
 
 proc = None
 
@@ -13,19 +11,22 @@ def start(args, logfile, errfile):
     proc = subprocess.Popen([
         bin_dir + "/gunicorn",
         "app:app",
-        "-k", "meinheld.gmeinheld.MeinheldWorker",
-        "-b", "0.0.0.0:8080",
-        '-w', str(NCPU*3),
-        "--log-level=critical"],
+        "-c", "gunicorn_conf.py"],
         cwd="falcon", stderr=errfile, stdout=logfile)
     return 0
 
 
 def stop(logfile, errfile):
+    global proc
+    if proc:
+        proc.terminate()
+        proc = None
+
     p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
     out, err = p.communicate()
     for line in out.splitlines():
       if 'FrameworkBenchmarks/installs/py2/bin/' in line:
-        pid = int(line.split(None,2)[1])
+        errfile.write("Killing: " + line + "\n")
+        pid = int(line.split()[1])
         os.kill(pid, 15)
     return 0

+ 2 - 6
falcon/setup_py3.py

@@ -1,9 +1,7 @@
 import subprocess
-import multiprocessing
 import os
 
 bin_dir = os.path.expanduser('~/FrameworkBenchmarks/installs/py3/bin')
-NCPU = multiprocessing.cpu_count()
 
 proc = None
 
@@ -13,13 +11,11 @@ def start(args, logfile, errfile):
     proc = subprocess.Popen([
         bin_dir + "/gunicorn",
         "app:app",
-        "-k", "meinheld.gmeinheld.MeinheldWorker",
-        "-b", "0.0.0.0:8080",
-        '-w', str(NCPU*3),
-        "--log-level=critical"],
+        "-c", "gunicorn_conf.py"],
         cwd="falcon", stderr=errfile, stdout=logfile)
     return 0
 
+
 def stop(logfile, errfile):
     global proc
     if proc is None:

+ 12 - 10
falcon/setup_pypy.py

@@ -1,9 +1,7 @@
 import subprocess
-import multiprocessing
 import os
 
 bin_dir = os.path.expanduser('~/FrameworkBenchmarks/installs/pypy/bin')
-NCPU = multiprocessing.cpu_count()
 
 proc = None
 
@@ -13,17 +11,21 @@ def start(args, logfile, errfile):
     proc = subprocess.Popen([
         bin_dir + "/gunicorn",
         "app:app",
-        '-k', 'tornado',
-        "-b", "0.0.0.0:8080",
-        '-w', str(NCPU*3),
-        "--log-level=critical"],
+        "-c", "gunicorn_conf.py"],
         cwd="falcon", stderr=errfile, stdout=logfile)
     return 0
 
 def stop(logfile, errfile):
     global proc
-    if proc is None:
-        return 0
-    proc.terminate()
-    proc = None
+    if proc:
+        proc.terminate()
+        proc = None
+
+    p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
+    out, err = p.communicate()
+    for line in out.splitlines():
+      if 'installs/pypy/bin/' in line:
+        errfile.write("Killing: " + line + "\n")
+        pid = int(line.split()[1])
+        os.kill(pid, 15)
     return 0

+ 3 - 0
falcore/install.sh

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

+ 2 - 0
finagle/install.sh

@@ -0,0 +1,2 @@
+#!/bin/bash
+

+ 28 - 16
flask/app.py

@@ -22,10 +22,10 @@ except ImportError:
 # setup
 
 app = Flask(__name__)
-app.config['SQLALCHEMY_DATABASE_URI'] = mysql_schema + '//benchmarkdbuser:benchmarkdbpass@DBHOSTNAME:3306/hello_world?charset=utf8'
+app.config['SQLALCHEMY_DATABASE_URI'] = mysql_schema + '//benchmarkdbuser:benchmarkdbpass@localhost:3306/hello_world?charset=utf8'
 app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False
 db = SQLAlchemy(app)
-dbraw_engine = create_engine(app.config['SQLALCHEMY_DATABASE_URI'])
+dbraw_engine = create_engine(app.config['SQLALCHEMY_DATABASE_URI'], connect_args={'autocommit': True}, pool_reset_on_return=None)
 
 # models
 
@@ -110,7 +110,9 @@ def get_fortunes():
 
 @app.route("/fortunesraw")
 def get_forutens_raw():
-    fortunes = list(dbraw_engine.execute("SELECT * FROM Fortune"))
+    res = dbraw_engine.execute("SELECT * FROM Fortune")
+    fortunes = res.fetchall()
+    res.close()
     fortunes.append(Fortune(id=0, message="Additional fortune added at request time."))
     fortunes.sort(key=attrgetter('message'))
     return render_template('fortunes.html', fortunes=fortunes)
@@ -138,19 +140,22 @@ def updates():
 @app.route("/raw-updates")
 def raw_updates():
     """Test 5: Database Updates"""
-    num_queries = request.args.get('queries', 1, type=int)
-    if num_queries > 500:
-        num_queries = 500
-
-    worlds = []
-    rp = partial(randint, 1, 10000)
-    for i in xrange(num_queries):
-        world = dbraw_engine.execute("SELECT * FROM World WHERE id=%s", (rp(),)).fetchone()
-        randomNumber = rp()
-        worlds.append({'id': world['id'], 'randomNumber': randomNumber})
-        dbraw_engine.execute("UPDATE World SET randomNumber=%s WHERE id=%s",
-                             (randomNumber, world['id']))
-    return json_response(worlds)
+    connection = dbraw_engine.connect()
+    try:
+        num_queries = request.args.get('queries', 1, type=int)
+        if num_queries > 500:
+            num_queries = 500
+
+        worlds = []
+        rp = partial(randint, 1, 10000)
+        for i in xrange(num_queries):
+            world = connection.execute("SELECT * FROM World WHERE id=%s", (rp(),)).fetchone()
+            randomNumber = rp()
+            worlds.append({'id': world['id'], 'randomNumber': randomNumber})
+            connection.execute("UPDATE World SET randomNumber=%s WHERE id=%s", (randomNumber, world['id']))
+        return json_response(worlds)
+    finally:
+        connection.close()
 
 
 @app.route('/plaintext')
@@ -161,6 +166,13 @@ def plaintext():
     return response
 
 
+try:
+    import meinheld
+    meinheld.server.set_access_logger(None)
+    meinheld.set_keepalive(120)
+except ImportError:
+    pass
+
 # entry point for debugging
 if __name__ == "__main__":
     app.run(debug=True)

+ 7 - 7
flask/benchmark_config

@@ -16,7 +16,7 @@
       "framework": "flask",
       "language": "Python",
       "orm": "Full",
-      "platform": "Gunicorn/Meinheld",
+      "platform": "Meinheld",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
@@ -37,7 +37,7 @@
       "framework": "flask",
       "language": "Python",
       "orm": "Raw",
-      "platform": "Gunicorn/Meinheld",
+      "platform": "Meinheld",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
@@ -60,7 +60,7 @@
       "framework": "flask",
       "language": "Python",
       "orm": "Full",
-      "platform": "Gunicorn/Meinheld",
+      "platform": "Meinheld",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
@@ -83,12 +83,12 @@
       "framework": "flask",
       "language": "Python",
       "orm": "Full",
-      "platform": "Gunicorn/Tornado",
+      "platform": "Tornado",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "flask-pypy",
-      "notes": "PyPy 2.2",
+      "notes": "PyPy 2.3",
       "versus": "wsgi"
     },
     "pypy-mysql-raw": {
@@ -104,12 +104,12 @@
       "framework": "flask",
       "language": "Python",
       "orm": "Raw",
-      "platform": "Gunicorn/Tornado",
+      "platform": "Tornado",
       "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "flask-pypy-raw",
-      "notes": "PyPy 2.2",
+      "notes": "PyPy 2.3",
       "versus": "wsgi"
     },
     "nginx-uwsgi": {

+ 3 - 0
flask/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends python2 python3 pypy

+ 1 - 0
flask/requirements.txt

@@ -0,0 +1 @@
+Chaussette

+ 28 - 14
flask/setup.py

@@ -6,24 +6,38 @@ import os
 bin_dir = os.path.expanduser('~/FrameworkBenchmarks/installs/py2/bin')
 NCPU = multiprocessing.cpu_count()
 
+CIRCUS_INI = """\
+[watcher:app]
+cmd = {BIN}/chaussette --fd=$(circus.sockets.app) --backend=meinheld app.app
+use_sockets = True
+numprocesses = {PROCS}
+
+[socket:app]
+host = 0.0.0.0
+port = 8080
+"""
+
+proc = None
 
 def start(args, logfile, errfile):
+    global proc
+
+    subprocess.check_call(bin_dir + "/pip install -r requirements.txt",
+                          cwd="flask", stderr=errfile, stdout=logfile, shell=True)
+
+    with open("flask/circus.ini", "w") as f:
+        f.write(CIRCUS_INI.format(BIN=bin_dir, PROCS=NCPU*3))
+
     setup_util.replace_text("flask/app.py", "DBHOSTNAME", args.database_host)
-    subprocess.Popen([
-        bin_dir + "/gunicorn",
-        "app:app",
-        "-k", "meinheld.gmeinheld.MeinheldWorker",
-        "-b", "0.0.0.0:8080",
-        '-w', str(NCPU*3),
-        "--log-level=critical"],
-        cwd="flask", stderr=errfile, stdout=logfile)
+    proc = subprocess.Popen([bin_dir + "/circusd", "circus.ini"],
+		            cwd="flask", stderr=errfile, stdout=logfile)
     return 0
 
 def stop(logfile, errfile):
-    p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
-    out, err = p.communicate()
-    for line in out.splitlines():
-      if 'FrameworkBenchmarks/installs/py2/bin/' in line:
-        pid = int(line.split(None,2)[1])
-        os.kill(pid, 15)
+    global proc
+    if proc is None:
+        return 0
+    proc.terminate()
+    proc.wait()
+    proc = None
     return 0

+ 24 - 9
flask/setup_py3.py

@@ -3,21 +3,36 @@ import setup_util
 import multiprocessing
 import os
 
-bin_dir = os.path.expanduser('~/FrameworkBenchmarks/installs/py3/bin')
+PY2BIN = os.path.expanduser('~/FrameworkBenchmarks/installs/py2/bin')
+PY3BIN = os.path.expanduser('~/FrameworkBenchmarks/installs/py3/bin')
 NCPU = multiprocessing.cpu_count()
 
+CIRCUS_INI = """\
+[watcher:app]
+cmd = {BIN}/chaussette --fd=$(circus.sockets.app) --backend=meinheld app.app
+use_sockets = True
+numprocesses = {PROCS}
+
+[socket:app]
+host = 0.0.0.0
+port = 8080
+"""
+
+proc = None
+
 
 def start(args, logfile, errfile):
     global proc
+
+    subprocess.check_call(PY3BIN + "/pip3 install -r requirements.txt",
+                          cwd="flask", stderr=errfile, stdout=logfile, shell=True)
+
+    with open("flask/circus.ini", "w") as f:
+        f.write(CIRCUS_INI.format(BIN=PY3BIN, PROCS=NCPU*3))
+
     setup_util.replace_text("flask/app.py", "DBHOSTNAME", args.database_host)
-    proc = subprocess.Popen([
-        bin_dir + "/gunicorn",
-        "app:app",
-        "-k", "meinheld.gmeinheld.MeinheldWorker",
-        "-b", "0.0.0.0:8080",
-        '-w', str(NCPU*3),
-        "--log-level=critical"],
-        cwd="flask", stderr=errfile, stdout=logfile)
+    proc = subprocess.Popen([PY2BIN + "/circusd", "circus.ini"],
+		            cwd="flask", stderr=errfile, stdout=logfile)
     return 0
 
 def stop(logfile, errfile):

+ 1 - 1
flask/setup_pypy.py

@@ -15,7 +15,7 @@ def start(args, logfile, errfile):
     proc = subprocess.Popen([
         bin_dir + "/gunicorn",
         "app:app",
-        '-k', 'tornado',
+        "-k", "tornado",
         "-b", "0.0.0.0:8080",
         '-w', str(NCPU*3),
         "--log-level=critical"],

+ 3 - 0
gemini/install.sh

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

+ 3 - 0
go/install.sh

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

+ 3 - 0
grails/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends grails resin 

+ 3 - 0
grizzly-bm/install.sh

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

+ 3 - 0
grizzly-jersey/install.sh

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

+ 3 - 0
hapi/install.sh

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

+ 3 - 0
hhvm/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends hhvm php

+ 2 - 0
http-kit/install.sh

@@ -0,0 +1,2 @@
+#!/bin/bash
+

+ 3 - 0
jester/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends jester nimrod nginx 

+ 3 - 0
jetty-servlet/install.sh

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

+ 3 - 0
kelp/install.sh

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

+ 3 - 0
lapis/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends lapis nginx openresty

+ 2 - 0
lift-stateless/install.sh

@@ -0,0 +1,2 @@
+#!/bin/bash
+

+ 3 - 0
luminus/install.sh

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

+ 3 - 0
mojolicious/install.sh

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

+ 3 - 0
nancy/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends nginx xsp

+ 3 - 0
nawak/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends nawak nimrod mongrel2

+ 2 - 2
netty/README.md

@@ -8,8 +8,8 @@ This is the netty portion of a [benchmarking test suite](../) comparing a variet
 ## Versions
 
 * [Java OpenJDK 1.7.0_09](http://openjdk.java.net/)
-* [Netty 4.0.16](http://netty.io/)
-* [Jackson 2.3.1](http://wiki.fasterxml.com/JacksonHome)
+* [Netty 4.0.21](http://netty.io/)
+* [Jackson 2.4.1](http://wiki.fasterxml.com/JacksonHome)
 
 ## References
 * https://github.com/netty/netty/tree/master/example/src/main/java/io/netty/example/http/snoop

+ 3 - 0
netty/install.sh

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

+ 5 - 4
netty/pom.xml

@@ -13,22 +13,23 @@
 		<dependency>
 			<groupId>io.netty</groupId>
 			<artifactId>netty-codec-http</artifactId>
-			<version>4.0.17.Final</version>
+			<version>4.0.21.Final</version>
 		</dependency>
 		<dependency>
 			<groupId>io.netty</groupId>
 			<artifactId>netty-transport-native-epoll</artifactId>
-			<version>4.0.17.Final</version>
+			<version>4.0.21.Final</version>
+			<classifier>linux-x86_64</classifier>
 		</dependency>
 		<dependency>
 			<groupId>com.fasterxml.jackson.core</groupId>
 			<artifactId>jackson-databind</artifactId>
-			<version>2.3.1</version>
+			<version>RELEASE</version>
 		</dependency>
 		<dependency>
 			<groupId>com.fasterxml.jackson.module</groupId>
 			<artifactId>jackson-module-afterburner</artifactId>
-			<version>2.3.1</version>
+			<version>RELEASE</version>
 		</dependency>
 		<dependency>
 			<groupId>javassist</groupId>

+ 57 - 66
netty/src/main/java/hello/HelloServerHandler.java

@@ -3,7 +3,6 @@ package hello;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import io.netty.channel.ChannelFutureListener;
-import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.SimpleChannelInboundHandler;
 import io.netty.handler.codec.http.DefaultFullHttpResponse;
@@ -13,6 +12,7 @@ import io.netty.handler.codec.http.HttpRequest;
 import io.netty.handler.codec.http.HttpResponseStatus;
 import io.netty.handler.codec.http.HttpVersion;
 import io.netty.util.CharsetUtil;
+import io.netty.util.concurrent.FastThreadLocal;
 
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
@@ -23,20 +23,16 @@ import java.util.concurrent.TimeUnit;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
 
[email protected]
 public class HelloServerHandler extends SimpleChannelInboundHandler<Object> {
-	private static final ThreadLocal<DateFormat> FORMAT = new ThreadLocal<DateFormat>() {
-        @Override
-        protected DateFormat initialValue() {
-            return new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z");
-        }
+    private static final FastThreadLocal<DateFormat> FORMAT = new FastThreadLocal<DateFormat>() {
+	@Override
+	protected DateFormat initialValue() {
+	    return new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z");
+	}
     };
 
-
-    private static final ByteBuf CONTENT_BUFFER = Unpooled.unreleasableBuffer(
-            Unpooled.directBuffer().writeBytes("Hello, World!".getBytes(CharsetUtil.UTF_8)));
-    private static final CharSequence contentLength = HttpHeaders.newEntity(
-            String.valueOf(CONTENT_BUFFER.readableBytes()));
+    private static final ByteBuf CONTENT_BUFFER = Unpooled.unreleasableBuffer(Unpooled.directBuffer().writeBytes("Hello, World!".getBytes(CharsetUtil.UTF_8)));
+    private static final CharSequence contentLength = HttpHeaders.newEntity(String.valueOf(CONTENT_BUFFER.readableBytes()));
 
     private static final CharSequence TYPE_PLAIN = HttpHeaders.newEntity("text/plain; charset=UTF-8");
     private static final CharSequence TYPE_JSON = HttpHeaders.newEntity("application/json; charset=UTF-8");
@@ -46,77 +42,72 @@ public class HelloServerHandler extends SimpleChannelInboundHandler<Object> {
     private static final CharSequence CONTENT_LENGTH_ENTITY = HttpHeaders.newEntity(HttpHeaders.Names.CONTENT_LENGTH);
     private static final CharSequence SERVER_ENTITY = HttpHeaders.newEntity(HttpHeaders.Names.SERVER);
     private static final ObjectMapper MAPPER;
-    
-    static{
-    	MAPPER = new ObjectMapper();
-    	MAPPER.registerModule(new AfterburnerModule());
+
+    static {
+	MAPPER = new ObjectMapper();
+	MAPPER.registerModule(new AfterburnerModule());
     }
-    
+
     private volatile CharSequence date = HttpHeaders.newEntity(FORMAT.get().format(new Date()));
 
     HelloServerHandler(ScheduledExecutorService service) {
-        service.scheduleWithFixedDelay(new Runnable() {
-            private final DateFormat format = FORMAT.get();
-            @Override
-            public void run() {
-                date = HttpHeaders.newEntity(format.format(new Date()));
-            }
-        }, 1000, 1000, TimeUnit.MILLISECONDS);
+	service.scheduleWithFixedDelay(new Runnable() {
+	    private final DateFormat format = FORMAT.get();
+
+	    @Override
+	    public void run() {
+		date = HttpHeaders.newEntity(format.format(new Date()));
+	    }
+	}, 1000, 1000, TimeUnit.MILLISECONDS);
 
     }
 
     @Override
     public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
-        if (msg instanceof HttpRequest) {
-            HttpRequest request = (HttpRequest) msg;
-            String uri = request.getUri();
-            switch (uri) {
-                case "/plaintext":
-                    writeResponse(ctx, request, CONTENT_BUFFER.duplicate(), TYPE_PLAIN, contentLength);
-                    return;
-                case "/json":
-                    byte[] json = MAPPER.writeValueAsBytes(new Message("Hello, World!"));
-                    writeResponse(ctx, request, Unpooled.wrappedBuffer(json), TYPE_JSON,
-                            String.valueOf(json.length));
-                    return;
-            }
-            FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND, Unpooled.EMPTY_BUFFER, false);
-            ctx.write(response).addListener(ChannelFutureListener.CLOSE);
-        }
+	if (msg instanceof HttpRequest) {
+	    HttpRequest request = (HttpRequest) msg;
+	    String uri = request.getUri();
+	    switch (uri) {
+	    case "/plaintext":
+		writeResponse(ctx, request, CONTENT_BUFFER.duplicate(), TYPE_PLAIN, contentLength);
+		return;
+	    case "/json":
+		byte[] json = MAPPER.writeValueAsBytes(new Message("Hello, World!"));
+		writeResponse(ctx, request, Unpooled.wrappedBuffer(json), TYPE_JSON, String.valueOf(json.length));
+		return;
+	    }
+	    FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND, Unpooled.EMPTY_BUFFER, false);
+	    ctx.write(response).addListener(ChannelFutureListener.CLOSE);
+	}
     }
 
-    private void writeResponse(ChannelHandlerContext ctx, HttpRequest request, ByteBuf buf,
-                               CharSequence contentType, CharSequence contentLength) {
-        // Decide whether to close the connection or not.
-        boolean keepAlive = HttpHeaders.isKeepAlive(request);
-        // Build the response object.
-        FullHttpResponse response = new DefaultFullHttpResponse(
-                HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf, false);
-        HttpHeaders headers = response.headers();
-        headers.set(CONTENT_TYPE_ENTITY, contentType);
-        headers.set(SERVER_ENTITY, SERVER_NAME);
-        headers.set(DATE_ENTITY, date);
-
-        if (keepAlive) {
-            headers.set(CONTENT_LENGTH_ENTITY, contentLength);
-        }
-
-        // Close the non-keep-alive connection after the write operation is done.
-        if (!keepAlive) {
-            ctx.write(response).addListener(ChannelFutureListener.CLOSE);
-        } else {
-            ctx.write(response, ctx.voidPromise());
-        }
+    private void writeResponse(ChannelHandlerContext ctx, HttpRequest request, ByteBuf buf, CharSequence contentType, CharSequence contentLength) {
+	// Decide whether to close the connection or not.
+	boolean keepAlive = HttpHeaders.isKeepAlive(request);
+	// Build the response object.
+	FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf, false);
+	HttpHeaders headers = response.headers();
+	headers.set(CONTENT_TYPE_ENTITY, contentType);
+	headers.set(SERVER_ENTITY, SERVER_NAME);
+	headers.set(DATE_ENTITY, date);
+	headers.set(CONTENT_LENGTH_ENTITY, contentLength);
+
+	// Close the non-keep-alive connection after the write operation is
+	// done.
+	if (!keepAlive) {
+	    ctx.write(response).addListener(ChannelFutureListener.CLOSE);
+	} else {
+	    ctx.write(response, ctx.voidPromise());
+	}
     }
 
     @Override
-    public void exceptionCaught(
-            ChannelHandlerContext ctx, Throwable cause) throws Exception {
-        ctx.close();
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+	ctx.close();
     }
 
     @Override
     public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
-        ctx.flush();
+	ctx.flush();
     }
 }

+ 9 - 7
netty/src/main/java/hello/HelloServerInitializer.java

@@ -1,6 +1,5 @@
 package hello;
 
-import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelInitializer;
 import io.netty.channel.ChannelPipeline;
 import io.netty.channel.socket.SocketChannel;
@@ -10,15 +9,18 @@ import io.netty.handler.codec.http.HttpResponseEncoder;
 import java.util.concurrent.ScheduledExecutorService;
 
 public class HelloServerInitializer extends ChannelInitializer<SocketChannel> {
-    private final ChannelHandler httpHandler;
+
+    private ScheduledExecutorService service;
+
     public HelloServerInitializer(ScheduledExecutorService service) {
-        this.httpHandler = new HelloServerHandler(service);
+	this.service = service;
     }
+
     @Override
     public void initChannel(SocketChannel ch) throws Exception {
-        ChannelPipeline p = ch.pipeline();
-        p.addLast("encoder", new HttpResponseEncoder());
-        p.addLast("decoder", new HttpRequestDecoder(4096, 8192, 8192, false));
-        p.addLast("handler", httpHandler);
+	ChannelPipeline p = ch.pipeline();
+	p.addLast("encoder", new HttpResponseEncoder());
+	p.addLast("decoder", new HttpRequestDecoder(4096, 8192, 8192, false));
+	p.addLast("handler", new HelloServerHandler(service));
     }
 }

+ 33 - 39
netty/src/main/java/hello/HelloWebServer.java

@@ -6,6 +6,7 @@ import io.netty.channel.Channel;
 import io.netty.channel.ChannelOption;
 import io.netty.channel.EventLoopGroup;
 import io.netty.channel.ServerChannel;
+import io.netty.channel.epoll.Epoll;
 import io.netty.channel.epoll.EpollEventLoopGroup;
 import io.netty.channel.epoll.EpollServerSocketChannel;
 import io.netty.channel.nio.NioEventLoopGroup;
@@ -13,60 +14,53 @@ import io.netty.channel.socket.nio.NioServerSocketChannel;
 import io.netty.util.ResourceLeakDetector;
 import io.netty.util.ResourceLeakDetector.Level;
 
-
 public class HelloWebServer {
-	private static int IO_THREADS = Runtime.getRuntime().availableProcessors() * 2;
+
     static {
-        ResourceLeakDetector.setLevel(Level.DISABLED);
+	ResourceLeakDetector.setLevel(Level.DISABLED);
     }
 
     private final int port;
 
     public HelloWebServer(int port) {
-        this.port = port;
+	this.port = port;
     }
 
     public void run() throws Exception {
-		// Configure the server.
+	// Configure the server.
 
-		String os = System.getProperty("os.name").toLowerCase();
-
-		boolean is_linux = os.contains("linux");
-		
-		if (is_linux) {
-			doRun( new EpollEventLoopGroup(), EpollServerSocketChannel.class);
-		}
-		else {
-			doRun(new NioEventLoopGroup(), NioServerSocketChannel.class);
-		} 
+	if (Epoll.isAvailable()) {
+	    doRun(new EpollEventLoopGroup(), EpollServerSocketChannel.class);
+	} else {
+	    doRun(new NioEventLoopGroup(), NioServerSocketChannel.class);
+	}
     }
-    
-	private void doRun(EventLoopGroup loupGroup, Class<? extends ServerChannel> serverChannelClass) throws InterruptedException	{
-		try {
-			ServerBootstrap b = new ServerBootstrap();
-			b.option(ChannelOption.SO_BACKLOG, 1024);
-			b.option(ChannelOption.SO_REUSEADDR, true);
-			b.group(loupGroup).channel(serverChannelClass).childHandler(new HelloServerInitializer(loupGroup.next()));			
-            b.option(ChannelOption.MAX_MESSAGES_PER_READ, Integer.MAX_VALUE);
-            b.childOption(ChannelOption.ALLOCATOR, new PooledByteBufAllocator(true, IO_THREADS, IO_THREADS, 8192, 11));
-            b.childOption(ChannelOption.SO_REUSEADDR, true);
-            b.childOption(ChannelOption.MAX_MESSAGES_PER_READ, Integer.MAX_VALUE);
 
-			Channel ch = b.bind(port).sync().channel();
-			ch.closeFuture().sync();
-		}
-		finally {
-			loupGroup.shutdownGracefully().sync();
-		}
+    private void doRun(EventLoopGroup loupGroup, Class<? extends ServerChannel> serverChannelClass) throws InterruptedException {
+	try {
+	    ServerBootstrap b = new ServerBootstrap();
+	    b.option(ChannelOption.SO_BACKLOG, 1024);
+	    b.option(ChannelOption.SO_REUSEADDR, true);
+	    b.group(loupGroup).channel(serverChannelClass).childHandler(new HelloServerInitializer(loupGroup.next()));
+	    b.option(ChannelOption.MAX_MESSAGES_PER_READ, Integer.MAX_VALUE);
+	    b.childOption(ChannelOption.ALLOCATOR, new PooledByteBufAllocator(true));
+	    b.childOption(ChannelOption.SO_REUSEADDR, true);
+	    b.childOption(ChannelOption.MAX_MESSAGES_PER_READ, Integer.MAX_VALUE);
+
+	    Channel ch = b.bind(port).sync().channel();
+	    ch.closeFuture().sync();
+	} finally {
+	    loupGroup.shutdownGracefully().sync();
 	}
+    }
 
     public static void main(String[] args) throws Exception {
-        int port;
-        if (args.length > 0) {
-            port = Integer.parseInt(args[0]);
-        } else {
-            port = 8080;
-        }
-        new HelloWebServer(port).run();
+	int port;
+	if (args.length > 0) {
+	    port = Integer.parseInt(args[0]);
+	} else {
+	    port = 8080;
+	}
+	new HelloWebServer(port).run();
     }
 }

+ 9 - 9
netty/src/main/java/hello/Message.java

@@ -1,15 +1,15 @@
 package hello;
 
 public class Message {
-	
-	private final String message;
 
-	public Message(String message) {
-		super();
-		this.message = message;
-	}
+    private final String message;
 
-	public String getMessage() {
-		return message;
-	}
+    public Message(String message) {
+	super();
+	this.message = message;
+    }
+
+    public String getMessage() {
+	return message;
+    }
 }

+ 3 - 0
ninja-resin/install.sh

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

+ 3 - 0
ninja-standalone/install.sh

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

+ 3 - 0
nodejs/install.sh

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

+ 2 - 0
onion/install.sh

@@ -0,0 +1,2 @@
+#!/bin/bash
+

+ 3 - 0
openresty/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends openresty nginx

+ 3 - 0
php-codeigniter/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends php nginx

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