Browse Source

Merge branch 'master' into fortune

Patrick Falls 12 years ago
parent
commit
91c13b713f
65 changed files with 1100 additions and 96 deletions
  1. 24 0
      dancer/README.md
  2. 0 0
      dancer/__init__.py
  3. 28 0
      dancer/app.pl
  4. 19 0
      dancer/benchmark_config
  5. 37 0
      dancer/nginx.conf
  6. 32 0
      dancer/setup.py
  7. 42 16
      installer.py
  8. 23 0
      kelp/README.md
  9. 0 0
      kelp/__init__.py
  10. 31 0
      kelp/app.pl
  11. 19 0
      kelp/benchmark_config
  12. 37 0
      kelp/nginx.conf
  13. 32 0
      kelp/setup.py
  14. 32 0
      mojolicious/README.md
  15. 0 0
      mojolicious/__init__.py
  16. 31 0
      mojolicious/app.pl
  17. 19 0
      mojolicious/benchmark_config
  18. 37 0
      mojolicious/nginx.conf
  19. 32 0
      mojolicious/setup.py
  20. 2 2
      php-fuel/README.md
  21. 2 2
      php-kohana/README.md
  22. 2 2
      php-micromvc/README.md
  23. 1 1
      php-silex/README.md
  24. 3 3
      php-symfony2/README.md
  25. 4 4
      php-symfony2/app/config/config_prod.yml
  26. 3 3
      php-symfony2/web/app.php
  27. 23 0
      plack/app.psgi
  28. 11 1
      play-scala/app/controllers/Application.scala
  29. 24 0
      play-scala/app/models/Fortune.scala
  30. 1 1
      play-scala/app/models/World.scala
  31. 18 0
      play-scala/app/views/fortune.scala.html
  32. 13 0
      play-scala/app/views/main.scala.html
  33. 1 0
      play-scala/benchmark_config
  34. 1 0
      play-scala/conf/routes
  35. 54 16
      play1/app/controllers/Application.java
  36. 3 3
      play1/benchmark_config
  37. 14 6
      play1/conf/application.conf
  38. 4 2
      play1/conf/routes
  39. 7 7
      play1/setup.py
  40. 1 1
      rack/README.md
  41. 1 1
      rails-stripped/README.md
  42. 1 1
      rails/README.md
  43. 34 0
      ringojs-convinient/README.md
  44. 0 0
      ringojs-convinient/__init__.py
  45. 39 0
      ringojs-convinient/app/models.js
  46. 39 0
      ringojs-convinient/app/views.js
  47. 14 0
      ringojs-convinient/benchmark_config
  48. 9 0
      ringojs-convinient/ringo-main.js
  49. 28 0
      ringojs-convinient/setup.py
  50. 20 0
      ringojs-convinient/templates/fortunes.reinhardt
  51. 34 0
      ringojs/README.md
  52. 0 0
      ringojs/__init__.py
  53. 19 0
      ringojs/benchmark_config
  54. 11 0
      ringojs/config/log4j.properties
  55. 91 0
      ringojs/ringo-main.js
  56. 25 0
      ringojs/setup.py
  57. 7 6
      ringojs/templates/fortune.mustache
  58. 3 3
      run-tests.py
  59. 1 1
      sinatra/README.md
  60. 2 1
      spring/benchmark_config
  61. 15 0
      spring/src/main/java/hello/domain/Fortune.java
  62. 13 10
      spring/src/main/java/hello/web/HelloFortuneController.java
  63. 1 0
      spring/src/main/resources/hibernate.cfg.xml
  64. 22 0
      spring/src/main/webapp/WEB-INF/jsp/fortunes.jsp
  65. 4 3
      tornado/deploy/nginx.conf

+ 24 - 0
dancer/README.md

@@ -0,0 +1,24 @@
+# Setup
+
+* Perl 5.16.3
+* MySQL 5.5
+* Wrk 2.0
+
+# Requirements
+
+* Dancer
+* Dancer::Plugin::Database
+* DBD::mysql
+* Starman (if using Starman as web server)
+* Plack (for plackup)
+* nginx (if you want to front Dancer with nginx, nginx.conf provided)
+
+# Deployment
+
+Something along the lines of
+
+    plackup -E production -s Starman --workers=2 -l /tmp/frameworks-benchmark.sock -a ./app.pl
+
+if you want to front it with nginx, otherwise
+
+    plackup -E production -s Starman --port=8080 --workers=2 -a ./app.pl

+ 0 - 0
dancer/__init__.py


+ 28 - 0
dancer/app.pl

@@ -0,0 +1,28 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+use Dancer ':syntax';
+use Dancer::Plugin::Database;
+set serializer => 'JSON';
+
+#my $dbh = database({ driver => 'mysql', database => 'test' });
+my $dbh = database({ driver => 'mysql', host => 'localhost', database => 'hello_world', username => 'benchmarkdbuser', password => 'benchmarkdbpass' });
+
+get '/json' => sub {
+    { message => 'Hello, World!' }
+};
+
+get '/db' => sub {
+    my $queries = params->{queries} || 1;
+    my @response;
+    for( 1 .. $queries ) {
+        my $id = int rand 10000 + 1;
+        if ( my $row = $dbh->quick_select( 'world', { id => $id } ) ) {
+            push @response, { id => $id, randomNumber => $row->{randomNumber} };
+        }
+    }
+    { \@response }
+};
+
+Dancer->dance;

+ 19 - 0
dancer/benchmark_config

@@ -0,0 +1,19 @@
+{
+  "framework": "dancer",
+  "tests": [{
+    "default": {
+      "setup_file": "setup",
+      "json_url": "/json",
+      "port": 8080,
+      "sort": 76
+    },
+    "raw": {
+      "setup_file": "setup",
+      "db_url": "/db",
+      "query_url": "/db?queries=",
+      "port": 8080,
+      "sort": 77
+    }
+  }]
+}
+

+ 37 - 0
dancer/nginx.conf

@@ -0,0 +1,37 @@
+user pfalls;
+
+worker_processes 2;
+
+events {
+  worker_connections  1024;
+}
+
+http {
+  output_buffers   1 32k;
+  postpone_output  1460;
+
+  sendfile         on;
+  tcp_nopush       on;
+
+  tcp_nodelay      on;
+
+  upstream backendurl {
+    server unix:/home/pfalls/FrameworkBenchmarks/dancer/frameworks-benchmark.sock;
+  }
+
+  server {
+    listen 8080;
+    server_name localhost;
+
+    location / {
+      try_files $uri @proxy;
+      access_log off;
+      expires max;
+    }
+
+    location @proxy {
+      proxy_set_header Host $http_host;
+      proxy_pass http://backendurl;
+    }
+  }
+}

+ 32 - 0
dancer/setup.py

@@ -0,0 +1,32 @@
+import subprocess
+import sys
+import setup_util
+from os.path import expanduser
+import os
+import getpass
+
+home = expanduser("~")
+
+def start(args):
+  setup_util.replace_text("dancer/app.pl", "localhost", ""+ args.database_host +"")
+  setup_util.replace_text("dancer/nginx.conf", "USR", getpass.getuser())
+  setup_util.replace_text("dancer/nginx.conf", "server unix:.*\/FrameworkBenchmarks", "server unix:" + home + "/FrameworkBenchmarks")
+
+  try:
+    subprocess.Popen("plackup -E production -s Starman --workers=" + str(args.max_threads) + " -l " + home + "/FrameworkBenchmarks/dancer/frameworks-benchmark.sock -a ./app.pl", shell=True, cwd="dancer")
+    subprocess.check_call("sudo /usr/local/nginx/sbin/nginx -c " + home + "/FrameworkBenchmarks/dancer/nginx.conf", shell=True)
+    return 0
+  except subprocess.CalledProcessError:
+    return 1
+def stop():
+  try:
+    subprocess.call("sudo /usr/local/nginx/sbin/nginx -s stop", shell=True)
+    p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
+    out, err = p.communicate()
+    for line in out.splitlines():
+      if 'plackup' in line:
+        pid = int(line.split(None, 2)[1])
+        os.kill(pid, 9)
+    return 0
+  except subprocess.CalledProcessError:
+    return 1

+ 42 - 16
installer.py

@@ -2,7 +2,7 @@ import subprocess
 import os
 
 class Installer:
-  
+
   ############################################################
   # install_software
   ############################################################
@@ -22,7 +22,7 @@ class Installer:
     #######################################
     self.__run_command("sudo apt-get update", True)
     self.__run_command("sudo apt-get upgrade", True)    
-    self.__run_command("sudo apt-get install build-essential libpcre3 libpcre3-dev libpcrecpp0 libssl-dev zlib1g-dev python-software-properties unzip git-core libcurl4-openssl-dev libbz2-dev libmysqlclient-dev mongodb-clients libreadline6-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev libgdbm-dev ncurses-dev automake libffi-dev htop libtool bison libevent-dev libgstreamer-plugins-base0.10-0 libgstreamer0.10-0 liborc-0.4-0 libwxbase2.8-0 libwxgtk2.8-0 libgnutls-dev libjson0-dev libmcrypt-dev libicu-dev", True)
+    self.__run_command("sudo apt-get install build-essential libpcre3 libpcre3-dev libpcrecpp0 libssl-dev zlib1g-dev python-software-properties unzip git-core libcurl4-openssl-dev libbz2-dev libmysqlclient-dev mongodb-clients libreadline6-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev libgdbm-dev ncurses-dev automake libffi-dev htop libtool bison libevent-dev libgstreamer-plugins-base0.10-0 libgstreamer0.10-0 liborc-0.4-0 libwxbase2.8-0 libwxgtk2.8-0 libgnutls-dev libjson0-dev libmcrypt-dev libicu-dev cmake", True)
 
     self.__run_command("cp ../config/benchmark_profile ../../.bash_profile")
     self.__run_command("sudo sh -c \"echo '*               soft    nofile          8192' >> /etc/security/limits.conf\"")
@@ -38,7 +38,7 @@ class Installer:
     self.__run_command("wget -O - http://binaries.erlang-solutions.com/debian/erlang_solutions.asc | sudo apt-key add -")
     self.__run_command("sudo apt-get update")
     self.__run_command("sudo apt-get install esl-erlang", True)
-    
+
     #
     # Python
     #
@@ -62,10 +62,10 @@ class Installer:
     #
     # Java
     #
-    
+
     self.__run_command("sudo apt-get install openjdk-7-jdk", True)
     self.__run_command("sudo apt-get remove --purge openjdk-6-jre openjdk-6-jre-headless", True)
-    
+
     #
     # Ruby/JRuby
     #
@@ -76,7 +76,7 @@ class Installer:
     subprocess.call(["bash", "-c", "source ~/.rvm/scripts/'rvm' && rvm 2.0.0-p0 do gem install bundler"])
     subprocess.call(["bash", "-c", "source ~/.rvm/scripts/'rvm' && rvm install jruby-1.7.3"])
     subprocess.call(["bash", "-c", "source ~/.rvm/scripts/'rvm' && rvm jruby-1.7.3 do gem install bundler"])
-    
+
     # We need a newer version of jruby-rack
     self.__run_command("git clone git://github.com/jruby/jruby-rack.git")
     subprocess.call(["bash", "-c", "cd installs/jruby-rack && source ~/.rvm/scripts/'rvm' && rvm jruby-1.7.3 do bundle install"])
@@ -116,6 +116,32 @@ class Installer:
 
     self.__run_command("sudo apt-get install ghc cabal-install", True)
 
+    #
+    # RingoJs
+    #
+    self.__run_command("wget http://www.ringojs.org/downloads/ringojs_0.9-1_all.deb")
+    self.__run_command("sudo apt-get install jsvc")
+    self.__run_command("sudo dpkg -i ringojs_0.9-1_all.deb")
+    self.__run_command("rm ringojs_0.9-1_all.deb")
+    self.__run_command("sudo ringo-admin install oberhamsi/sql-ringojs-client")
+    self.__run_command("sudo ringo-admin install ringo/stick")
+    self.__run_command("sudo ringo-admin install oberhamsi/reinhardt")
+    self.__run_command("sudo ringo-admin install grob/ringo-sqlstore")
+
+    #
+    # Perl
+    #
+    self.__run_command("sudo cpan install Plack", send_yes=True)
+    self.__run_command("sudo cpan install Starman")
+    self.__run_command("sudo cpan install DBD::mysql")
+    self.__run_command("sudo cpan install DBI")
+    self.__run_command("sudo cpan install Dancer")
+    self.__run_command("sudo cpan install Dancer::Plugin::Database")
+    self.__run_command("sudo cpan install JSON", send_yes=True)
+    self.__run_command("sudo cpan install Kelp", send_yes=True)
+    self.__run_command("sudo cpan install Mojolicious", send_yes=True)
+    self.__run_command("sudo cpan install Mojolicious:Plugin:Database", send_yes=True)
+
     #######################################
     # Webservers
     #######################################
@@ -130,7 +156,7 @@ class Installer:
     self.__run_command("sudo mv /etc/apache2/ports.conf /etc/apache2/ports.conf.orig")
     self.__run_command("sudo sh -c \"cat ../config/ports.conf > /etc/apache2/ports.conf\"")
     self.__run_command("sudo /etc/init.d/apache2 stop")
-    
+
     #
     # Nginx
     #
@@ -138,7 +164,7 @@ class Installer:
     self.__run_command("./configure", cwd="nginx-1.2.7")
     self.__run_command("make", cwd="nginx-1.2.7")
     self.__run_command("sudo make install", cwd="nginx-1.2.7")
-    
+
     #
     # Openresty (nginx with openresty stuff)
     #
@@ -146,7 +172,7 @@ class Installer:
     self.__run_command("./configure --with-luajit", cwd="ngx_openresty-1.2.7.5")
     self.__run_command("make", cwd="ngx_openresty-1.2.7.5")
     self.__run_command("sudo make install", cwd="ngx_openresty-1.2.7.5")
-    
+
     #
     # Gunicorn
     #
@@ -224,7 +250,7 @@ class Installer:
     self.__run_command("wget http://dist.springframework.org.s3.amazonaws.com/release/GRAILS/grails-2.1.1.zip")
     self.__run_command("unzip -o grails-2.1.1.zip")
     self.__run_command("rm grails-2.1.1.zip")
-    
+
 
     ##############################
     # Flask
@@ -237,7 +263,7 @@ class Installer:
     self.__run_command("wget http://downloads.typesafe.com/play/2.1.1/play-2.1.1.zip")
     self.__run_command("unzip -o play-2.1.1.zip")
     self.__run_command("rm play-2.1.1.zip")
-    
+
     ##############################
     # Play 1
     ##############################
@@ -245,7 +271,7 @@ class Installer:
     self.__run_command("unzip -o play-1.2.5.zip")
     self.__run_command("rm play-1.2.5.zip")
     self.__run_command("mv play-1.2.5/play play-1.2.5/play1")
-    
+
     # siena
     self.__run_command("play-1.2.5/play1 install siena", send_yes=True)
 
@@ -323,7 +349,7 @@ class Installer:
     ./waf build
     sudo ./waf install
     cd ~
-    
+
     ##############################
     # wrk
     ##############################
@@ -339,16 +365,16 @@ class Installer:
     ##############################
     sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10
     sudo cp 10gen.list /etc/apt/sources.list.d/10gen.list
-    sudo apt-get update 
+    sudo apt-get update
     yes | sudo apt-get install mongodb-10gen
-    
+
     sudo mv /etc/mongodb.conf /etc/mongodb.conf.orig
     sudo mv mongodb.conf /etc/mongodb.conf
     sudo restart mongodb
     """
     p = subprocess.Popen(self.benchmarker.ssh_string.split(" "), stdin=subprocess.PIPE)
     p.communicate(remote_script)
-    
+
   ############################################################
   # End __parse_results
   ############################################################

+ 23 - 0
kelp/README.md

@@ -0,0 +1,23 @@
+# Setup
+
+* Perl 5.10+
+* MySQL 5.5
+* Wrk 2.0
+
+# Requirements
+
+* Kelp
+* DBD::mysql
+* Starman (if using Starman as web server)
+* Plack (for plackup)
+* nginx (if you want to front Dancer with nginx, nginx.conf provided)
+
+# Deployment
+
+Something along the lines of
+
+    plackup -E production -s Starman --workers=2 -l /tmp/frameworks-benchmark.sock -a ./app.pl
+
+if you want to front it with nginx, otherwise
+
+    plackup -E production -s Starman --port=8080 --workers=2 -a ./app.pl

+ 0 - 0
kelp/__init__.py


+ 31 - 0
kelp/app.pl

@@ -0,0 +1,31 @@
+#!/usr/bin/env perl
+use Kelp::Less;
+use DBI;
+
+attr dbh => sub {
+    my $database = 'hello_world';
+    my $host     = 'localhost';
+    my $dsn      = 'dbi:mysql:database=hello_world;host=localhost;port=3306';
+    DBI->connect( $dsn, 'benchmarkdbuser', 'benchmarkdbpass', {} );
+};
+
+get '/json' => sub {
+    { message => 'Hello, World!' }
+};
+
+get '/db' => sub {
+    my $self = shift;
+    my $queries = param('queries') || 1;
+    my @response;
+    my $sth = $self->dbh->prepare( 'SELECT randomnumber FROM world WHERE id = ?' );
+    for ( 1 .. $queries ) {
+        my $id = int rand 10000 + 1;
+        my $res = $sth->execute( $id );
+        if ( my $row = $sth->fetchrow_arrayref ) {
+            push @response, { id => $id, randomNumber => $row->[0] };
+        }
+    }
+    { \@response }
+};
+
+run;

+ 19 - 0
kelp/benchmark_config

@@ -0,0 +1,19 @@
+{
+  "framework": "kelp",
+  "tests": [{
+    "default": {
+      "setup_file": "setup",
+      "json_url": "/json",
+      "port": 8080,
+      "sort": 78
+    },
+    "raw": {
+      "setup_file": "setup",
+      "db_url": "/db",
+      "query_url": "/db?queries=",
+      "port": 8080,
+      "sort": 79
+    }
+  }]
+}
+

+ 37 - 0
kelp/nginx.conf

@@ -0,0 +1,37 @@
+user USR;
+
+worker_processes 2;
+
+events {
+  worker_connections  1024;
+}
+
+http {
+  output_buffers   1 32k;
+  postpone_output  1460;
+
+  sendfile         on;
+  tcp_nopush       on;
+
+  tcp_nodelay      on;
+
+  upstream backendurl {
+    server unix:/home/ubuntu/FrameworkBenchmarks/kelp/frameworks-benchmark.sock;
+  }
+
+  server {
+    listen 8080;
+    server_name localhost;
+
+    location / {
+      try_files $uri @proxy;
+      access_log off;
+      expires max;
+    }
+
+    location @proxy {
+      proxy_set_header Host $http_host;
+      proxy_pass http://backendurl;
+    }
+  }
+}

+ 32 - 0
kelp/setup.py

@@ -0,0 +1,32 @@
+import subprocess
+import sys
+import setup_util
+from os.path import expanduser
+import os
+import getpass
+
+home = expanduser("~")
+
+def start(args):
+  setup_util.replace_text("kelp/app.pl", "localhost", ""+ args.database_host +"")
+  setup_util.replace_text("kelp/nginx.conf", "USR", getpass.getuser())
+  setup_util.replace_text("kelp/nginx.conf", "server unix:.*\/FrameworkBenchmarks", "server unix:" + home + "/FrameworkBenchmarks")
+
+  try:
+    subprocess.Popen("plackup -E production -s Starman --workers=" + str(args.max_threads) + " -l " + home + "/FrameworkBenchmarks/kelp/frameworks-benchmark.sock -a ./app.pl", shell=True, cwd="kelp")
+    subprocess.check_call("sudo /usr/local/nginx/sbin/nginx -c " + home + "/FrameworkBenchmarks/kelp/nginx.conf", shell=True)
+    return 0
+  except subprocess.CalledProcessError:
+    return 1
+def stop():
+  try:
+    subprocess.call("sudo /usr/local/nginx/sbin/nginx -s stop", shell=True)
+    p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
+    out, err = p.communicate()
+    for line in out.splitlines():
+      if 'plackup' in line:
+        pid = int(line.split(None, 2)[1])
+        os.kill(pid, 9)
+    return 0
+  except subprocess.CalledProcessError:
+    return 1

+ 32 - 0
mojolicious/README.md

@@ -0,0 +1,32 @@
+# Setup
+
+* Perl 5.16.3
+* MySQL 5.5
+* Wrk 2.0
+
+# Requirements
+
+* Mojolicious
+* Mojolicious::Plugin::Database
+* DBD::mysql
+* Starman (if using Starman as web server)
+* Plack (for plackup)
+* nginx (if you want to front Mojolicious
+with nginx, nginx.conf provided)
+* Morbo and Hypnotoad provided by Mojolicious
+
+# Deployment
+
+Set production mode:
+
+    export MOJO_MODE=production
+
+Something along the lines of
+
+    plackup -s Starman --workers=2 -l /tmp/frameworks-benchmark.sock -a ./app.pl
+
+if you want to front it with nginx, otherwise
+
+    plackup -s Starman --port 8080 --workers=2 -a ./app.pl
+
+or the equivalent Morbo or Hypnotoad commands.

+ 0 - 0
mojolicious/__init__.py


+ 31 - 0
mojolicious/app.pl

@@ -0,0 +1,31 @@
+#!/usr/bin/env perl
+use Mojolicious::Lite;
+use Mojolicious::Plugin::Database;
+
+plugin 'database', {
+    dsn      => 'dbi:mysql:dbname=hello_world;host=localhost',
+    username => 'benchmarkdbuser',
+    password => 'benchmarkdbpass'
+};
+
+get '/json' => sub {
+    my $self = shift;
+    $self->render( json => { message => 'Hello, world!' } );
+};
+
+get '/db' => sub {
+    my $self = shift;
+    my $queries = $self->param('queries') || 1;
+    my @response;
+    my $sth = $self->db->prepare( 'SELECT randomnumber FROM world WHERE id = ?' );
+    for ( 1 .. $queries ) {
+        my $id = int rand 10000 + 1;
+        my $res = $sth->execute( $id );
+        if ( my $row = $sth->fetchrow_arrayref ) {
+            push @response, { id => $id, randomNumber => $row->[0] };
+        }
+    }
+    $self->render( json => \@response );
+};
+
+app->start;

+ 19 - 0
mojolicious/benchmark_config

@@ -0,0 +1,19 @@
+{
+  "framework": "mojolicious",
+  "tests": [{
+    "default": {
+      "setup_file": "setup",
+      "json_url": "/json",
+      "port": 8080,
+      "sort": 80
+    },
+    "raw": {
+      "setup_file": "setup",
+      "db_url": "/db",
+      "query_url": "/db?queries=",
+      "port": 8080,
+      "sort": 81
+    }
+  }]
+}
+

+ 37 - 0
mojolicious/nginx.conf

@@ -0,0 +1,37 @@
+user USR;
+
+worker_processes 2;
+
+events {
+  worker_connections  1024;
+}
+
+http {
+  output_buffers   1 32k;
+  postpone_output  1460;
+
+  sendfile         on;
+  tcp_nopush       on;
+
+  tcp_nodelay      on;
+
+  upstream backendurl {
+    server unix:/home/ubuntu/FrameworkBenchmarks/mojolicious/frameworks-benchmark.sock;
+  }
+
+  server {
+    listen 8080;
+    server_name localhost;
+
+    location / {
+      try_files $uri @proxy;
+      access_log off;
+      expires max;
+    }
+
+    location @proxy {
+      proxy_set_header Host $http_host;
+      proxy_pass http://backendurl;
+    }
+  }
+}

+ 32 - 0
mojolicious/setup.py

@@ -0,0 +1,32 @@
+import subprocess
+import sys
+import setup_util
+from os.path import expanduser
+import os
+import getpass
+
+home = expanduser("~")
+
+def start(args):
+  setup_util.replace_text("mojolicious/app.pl", "localhost", ""+ args.database_host +"")
+  setup_util.replace_text("mojolicious/nginx.conf", "USR", getpass.getuser())
+  setup_util.replace_text("mojolicious/nginx.conf", "server unix:.*\/FrameworkBenchmarks", "server unix:" + home + "/FrameworkBenchmarks")
+
+  try:
+    subprocess.Popen("plackup -E production -s Starman --workers=" + str(args.max_threads) + " -l " + home + "/FrameworkBenchmarks/mojolicious/frameworks-benchmark.sock -a ./app.pl", shell=True, cwd="mojolicious")
+    subprocess.check_call("sudo /usr/local/nginx/sbin/nginx -c " + home + "/FrameworkBenchmarks/mojolicious/nginx.conf", shell=True)
+    return 0
+  except subprocess.CalledProcessError:
+    return 1
+def stop():
+  try:
+    subprocess.call("sudo /usr/local/nginx/sbin/nginx -s stop", shell=True)
+    p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
+    out, err = p.communicate()
+    for line in out.splitlines():
+      if 'plackup' in line:
+        pid = int(line.split(None, 2)[1])
+        os.kill(pid, 9)
+    return 0
+  except subprocess.CalledProcessError:
+    return 1

+ 2 - 2
php-fuel/README.md

@@ -5,13 +5,13 @@ This is the FuelPHP portion of a [benchmarking test suite](../) comparing a vari
 ### JSON Encoding Test
 Uses the PHP standard [JSON encoder](http://www.php.net/manual/en/function.json-encode.php).
 
-* [JSON test controller](fuel/app/classes/controllers/bench.php)
+* [JSON test controller](fuel/app/classes/controller/bench.php)
 
 
 ### Data-Store/Database Mapping Test
 Uses the Fuel ORM
 
-* [DB test controller](fuel/app/classes/controllers/bench.php)
+* [DB test controller](fuel/app/classes/controller/bench.php)
 
 
 ## Infrastructure Software Versions

+ 2 - 2
php-kohana/README.md

@@ -5,13 +5,13 @@ This is the Kohana PHP portion of a [benchmarking test suite](../) comparing a v
 ### JSON Encoding Test
 Uses the PHP standard [JSON encoder](http://www.php.net/manual/en/function.json-encode.php).
 
-* [JSON test controller](application/classes/controllers/Bench.php)
+* [JSON test controller](application/classes/Controller/Bench.php)
 
 
 ### Data-Store/Database Mapping Test
 Uses the db abstraction class from Kohana
 
-* [DB test controller](application/classes/controllers/Bench.php)
+* [DB test controller](application/classes/Controller/Bench.php)
 
 
 ## Infrastructure Software Versions

+ 2 - 2
php-micromvc/README.md

@@ -5,13 +5,13 @@ This is the Micromvc portion of a [benchmarking test suite](../) comparing a var
 ### JSON Encoding Test
 Uses the PHP standard [JSON encoder](http://www.php.net/manual/en/function.json-encode.php).
 
-* [JSON test controller](index.php)
+* [JSON test controller](Class/Controller/Benchmark/Json.php)
 
 
 ### Data-Store/Database Mapping Test
 Uses the built-in ORM of micromvc
 
-* [DB test controller](index.php)
+* [DB test controller](Class/Controller/Benchmark/Db.php)
 
 
 ## Infrastructure Software Versions

+ 1 - 1
php-silex/README.md

@@ -1,4 +1,4 @@
-# Cake PHP Benchmarking Test
+# Silex Benchmarking Test
 
 This is the Silex PHP portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
 

+ 3 - 3
php-symfony2/README.md

@@ -1,4 +1,4 @@
-# Cake PHP Benchmarking Test
+# Symfony 2 Benchmarking Test
 
 This is the Symfony 2 PHP portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
 
@@ -11,8 +11,8 @@ Uses the PHP standard [JSON encoder](http://www.php.net/manual/en/function.json-
 ### Data-Store/Database Mapping Test
 Uses the Symfony 2/Doctrine 2 Entity functionality.
 
-* [DB test controller](src/Skamander/BenchmarkBundle/BenchController.php)
-* [DB test model](src/Skamander/BenchmarkBundle/World.php)
+* [DB test controller](src/Skamander/BenchmarkBundle/Controller/BenchController.php)
+* [DB test model](src/Skamander/BenchmarkBundle/Entity/World.php)
 
 
 ## Infrastructure Software Versions

+ 4 - 4
php-symfony2/app/config/config_prod.yml

@@ -11,11 +11,11 @@ framework:
     #validation:
     #    cache: apc
 
-#doctrine:
-#    orm:
-#        metadata_cache_driver: apc
+doctrine:
+    orm:
+        metadata_cache_driver: apc
 #        result_cache_driver: apc
-#        query_cache_driver: apc
+        query_cache_driver: apc
 
 monolog:
     handlers:

+ 3 - 3
php-symfony2/web/app.php

@@ -8,10 +8,10 @@ $loader = require_once __DIR__.'/../app/bootstrap.php.cache';
 // Use APC for autoloading to improve performance.
 // Change 'sf2' to a unique prefix in order to prevent cache key conflicts
 // with other applications also using APC.
-/*
-$loader = new ApcClassLoader('sf2', $loader);
+
+$loader = new ApcClassLoader('symfony2Benchmark', $loader);
 $loader->register(true);
-*/
+
 
 require_once __DIR__.'/../app/AppKernel.php';
 //require_once __DIR__.'/../app/AppCache.php';

+ 23 - 0
plack/app.psgi

@@ -0,0 +1,23 @@
+# plackup -s Starman --workers N -E deployment app.psgi
+# -or-
+# plackup -s Twiggy::Prefork --max_workers N -E deployment app.psgi
+use v5.16;
+use Plack::Builder;
+use Plack::Request;
+use JSON::XS 'encode_json';
+use DBI;
+
+my $dbh = DBI->connect('dbi:mysql:dbname=test', 'root') || die $!;
+my $sth = $dbh->prepare('SELECT randomnumber FROM world WHERE id = ?');
+my $header = ['Content-Type' => 'application/json'];
+
+builder {
+    mount '/json' => sub { [ 200, $header, [ encode_json({ message => 'Hello, World!' })] ] },
+    mount '/dbi' => sub { [ 200, $header, [ encode_json([
+        map { id => $_->[0] + 0, randomnumber => $_->[1] },
+        grep exists $_->[1],
+        map [$_, $sth->execute($_) && $sth->fetchrow_array],
+        map int rand 10000 + 1,
+        1..Plack::Request->new(shift)->param('queries')//1
+    ]) ] ] }
+};

+ 11 - 1
play-scala/app/controllers/Application.scala

@@ -5,7 +5,7 @@ import play.api.mvc._
 import play.api.libs.json.Json
 import java.util.concurrent._
 import scala.concurrent._
-import models._
+import models.{World, Fortune}
 import utils._
 import scala.concurrent.Future
 
@@ -58,4 +58,14 @@ object Application extends Controller {
     }
   }
 
+  def fortunes() = PredicatedAction(isDbAvailable, ServiceUnavailable) {
+    Action {
+      Async {
+        Future(Fortune.getAll())(dbEc).map { fs =>
+          val fortunes =  fs :+ Fortune(anorm.NotAssigned, "Additional fortune added at request time.")
+          Ok(views.html.fortune(fortunes))
+        }
+      }
+    }
+  }
 }

+ 24 - 0
play-scala/app/models/Fortune.scala

@@ -0,0 +1,24 @@
+package models
+
+import play.api.db._
+import play.api.Play.current
+import anorm._
+import anorm.SqlParser._
+
+case class Fortune(id: Pk[Long], message: String)
+
+object Fortune {
+
+  val simpleRowParser = {
+    get[Pk[Long]]("fortune.id") ~
+    get[String]("fortune.message") map {
+      case id~message => Fortune(id, message)
+    }
+  }
+
+  def getAll(): List[Fortune] = {
+    DB.withConnection { implicit connection =>
+      SQL("SELECT * FROM Fortune").as(Fortune.simpleRowParser *)
+    }
+  }
+}

+ 1 - 1
play-scala/app/models/World.scala

@@ -37,7 +37,7 @@ object World {
    */
     def findById(id: Long): World = {
         DB.withConnection { implicit connection =>
-            SQL("SELECT * FROM world WHERE id = {id}").on(
+            SQL("SELECT * FROM World WHERE id = {id}").on(
                 "id" -> id
             ).as(World.simpleRowParser.single)
         }

+ 18 - 0
play-scala/app/views/fortune.scala.html

@@ -0,0 +1,18 @@
+@(fortunes: List[Fortune])
+
+@main("Testcase 4 :: Fortune :: FrameworkBenchmark") {
+    <table>
+        <tr>
+            <th>id</th>
+            <th>message</th>
+        </tr>
+
+        @fortunes.sortBy(_.message).map { case Fortune(id, message) =>
+            <tr>
+                <td>@id</td>
+                <td>@message</td>
+            </tr>
+        }
+
+    </table>
+}

+ 13 - 0
play-scala/app/views/main.scala.html

@@ -0,0 +1,13 @@
+@(title: String)(content: Html)
+
+<!DOCTYPE html>
+
+<html>
+<head>
+    <title>@title</title>
+    <meta charset=utf-8>
+</head>
+<body>
+    @content
+</body>
+</html>

+ 1 - 0
play-scala/benchmark_config

@@ -6,6 +6,7 @@
       "json_url": "/json",
       "db_url": "/db",
       "query_url": "/db?queries=",
+      "fortune_url": "/fortunes",
       "port": 9000,
       "sort": 32
     }

+ 1 - 0
play-scala/conf/routes

@@ -5,6 +5,7 @@
 # Home page
 GET     /json                           controllers.Application.json
 GET     /db                             controllers.Application.db(queries: Int ?= 1)
+GET     /fortunes                       controllers.Application.fortunes
 
 # Map static resources from the /public folder to the /assets URL path
 GET     /assets/*file                   controllers.Assets.at(path="/public", file)

+ 54 - 16
play1/app/controllers/Application.java

@@ -10,6 +10,7 @@ import java.util.concurrent.ExecutionException;
 import models.World;
 import play.db.jpa.JPAPlugin;
 import play.jobs.Job;
+import play.libs.F.Promise;
 import play.mvc.Controller;
 
 public class Application extends Controller {
@@ -23,17 +24,38 @@ public class Application extends Controller {
 		render();
 	}
 
+	public static void hello() {
+		renderText("hello world");
+	}
+
 	public static void json() {
 		Map<String, String> result = new HashMap<String, String>();
 		result.put("message", "Hello World!");
 		renderJSON(result);
 	}
 
+	/**
+	 * this version is used in the tests. it is the simplest and fastest.
+	 * 
+	 * @param queries
+	 */
+	public static void dbSync(int queries) {
+		if (queries == 0)
+			queries = 1;
+		final List<World> worlds = new ArrayList<World>();
+		for (int i = 0; i < queries; ++i) {
+			Long id = Long.valueOf(random.nextInt(TEST_DATABASE_ROWS) + 1);
+			World result = World.findById(id);
+			worlds.add(result);
+		}
+		renderJSON(worlds);
+	}
+
 	@play.db.jpa.NoTransaction
 	public static void setup() {
 		JPAPlugin plugin = play.Play.plugin(JPAPlugin.class);
 		plugin.startTx(true);
-		
+
 		// clean out the old
 		World.deleteAll();
 		System.out.println("DELETED");
@@ -42,19 +64,46 @@ public class Application extends Controller {
 			int randomNumber = random.nextInt(TEST_DATABASE_ROWS) + 1;
 			new World(i, randomNumber).save();
 			if (i % 100 == 0) {
-				
+
 				World.em().flush();
 				World.em().clear();
 				System.out.println("FLUSHED : " + i + "/" + TEST_DATABASE_ROWS);
-				
+
 			}
 		}
 		System.out.println("ADDED");
 		plugin.closeTx(false);
 	}
 
-	public static void db(int queries) throws InterruptedException,
-			ExecutionException {
+	/**
+	 * note this is method is much slower than the synchronous version
+	 */
+	public static void dbAsyncEachQuery(int queries)
+			throws InterruptedException, ExecutionException {
+		if (queries == 0)
+			queries = 1;
+		final int queryCount = queries;
+		List<Promise<World>> promises = new ArrayList<Promise<World>>();
+		for (int i = 0; i < queryCount; ++i) {
+			final Long id = Long
+					.valueOf(random.nextInt(TEST_DATABASE_ROWS) + 1);
+			Job<World> job = new Job<World>() {
+				public World doJobWithResult() throws Exception {
+					World result = World.findById(id);
+					return result;
+				};
+			};
+			promises.add(job.now());
+		}
+		List<World> result = await(Promise.waitAll(promises));
+		renderJSON(result);
+	}
+
+	/**
+	 * note this is method is a bit slower than the synchronous version
+	 */
+	public static void dbAsyncAllQueries(int queries)
+			throws InterruptedException, ExecutionException {
 		if (queries == 0)
 			queries = 1;
 		final int queryCount = queries;
@@ -74,15 +123,4 @@ public class Application extends Controller {
 		renderJSON(result);
 	}
 
-	public static void dbSync(int queries) {
-		if (queries == 0)
-			queries = 1;
-		final List<World> worlds = new ArrayList<World>();
-		for (int i = 0; i < queries; ++i) {
-			Long id = Long.valueOf(random.nextInt(TEST_DATABASE_ROWS) + 1);
-			World result = World.findById(id);
-			worlds.add(result);
-		}
-		renderJSON(worlds);
-	}
 }

+ 3 - 3
play1/benchmark_config

@@ -3,9 +3,9 @@
   "tests": [{
     "default": {
       "setup_file": "setup",
-      "json_url": "/play1/json",
-      "db_url": "/play1/db",
-      "query_url": "/play1/db?queries=",
+      "json_url": "/json",
+      "db_url": "/db",
+      "query_url": "/db?queries=",
       "port": 8080,
       "sort": 65
     }

+ 14 - 6
play1/conf/application.conf

@@ -30,6 +30,10 @@ date.format=yyyy-MM-dd
 # ~~~~~
 # If you need to change the HTTP port, uncomment this (default is set to 9000)
 # http.port=9000
+
+#modified to match previous port on test 
+http.port=8080
+
 #
 # By default the server listen for HTTP on the wilcard address.
 # You can restrict this.
@@ -100,6 +104,8 @@ date.format=yyyy-MM-dd
 db.pool.timeout=1000
 db.pool.maxSize=30
 db.pool.minSize=10
+
+
 #
 # If you want to reuse an existing Datasource from your application server, use:
 # db=java:/comp/env/jdbc/myDatasource
@@ -110,15 +116,16 @@ db.pool.minSize=10
 # db.destroyMethod=close
 db.driver= com.mysql.jdbc.Driver
 db.url=jdbc:mysql://localhost:3306/hello_world?jdbcCompliantTruncation=false&elideSetAutoCommits=true&useLocalSessionState=true&cachePrepStmts=true&cacheCallableStmts=true&alwaysSendSetIsolation=false&prepStmtCacheSize=4096&cacheServerConfiguration=true&prepStmtCacheSqlLimit=2048&zeroDateTimeBehavior=convertToNull&traceProtocol=false&useUnbufferedInput=false&useReadAheadInput=false&maintainTimeStats=false&useServerPrepStmts&cacheRSMetadata=true
+#db.url=jdbc:mysql://localhost:3306/hello_world
 db.user=benchmarkdbuser
 db.pass=benchmarkdbpass
-db.jndiName=DefaultDS
+#db.jndiName=DefaultDS
 
-db.default.driver= com.mysql.jdbc.Driver
-db.default.url=jdbc:mysql://localhost:3306/hello_world?jdbcCompliantTruncation=false&elideSetAutoCommits=true&useLocalSessionState=true&cachePrepStmts=true&cacheCallableStmts=true&alwaysSendSetIsolation=false&prepStmtCacheSize=4096&cacheServerConfiguration=true&prepStmtCacheSqlLimit=2048&zeroDateTimeBehavior=convertToNull&traceProtocol=false&useUnbufferedInput=false&useReadAheadInput=false&maintainTimeStats=false&useServerPrepStmts&cacheRSMetadata=true
-db.default.user=benchmarkdbuser
-db.default.pass=benchmarkdbpass
-db.default.jndiName=DefaultDS
+#db.default.driver= com.mysql.jdbc.Driver
+#db.default.url=jdbc:mysql://localhost:3306/hello_world?jdbcCompliantTruncation=false&elideSetAutoCommits=true&useLocalSessionState=true&cachePrepStmts=true&cacheCallableStmts=true&alwaysSendSetIsolation=false&prepStmtCacheSize=4096&cacheServerConfiguration=true&prepStmtCacheSqlLimit=2048&zeroDateTimeBehavior=convertToNull&traceProtocol=false&useUnbufferedInput=false&useReadAheadInput=false&maintainTimeStats=false&useServerPrepStmts&cacheRSMetadata=true
+#db.default.user=benchmarkdbuser
+#db.default.pass=benchmarkdbpass
+#db.default.jndiName=DefaultDS
 
 
 # JPA Configuration (Hibernate)
@@ -205,6 +212,7 @@ mail.smtp=mock
 # Size of the Jobs pool
 # play.jobs.pool=10
 
+
 # Execution pool
 # ~~~~~
 # Default to 1 thread in DEV mode or (nb processors + 1) threads in PROD mode.

+ 4 - 2
play1/conf/routes

@@ -5,8 +5,10 @@
 
 # Home page
 GET     /json                           Application.json
-GET     /db                             Application.db
-GET     /db_sync                        Application.dbSync
+GET     /db                             Application.dbSync
+GET     /db2                            Application.dbAsyncAllQueries
+GET     /db3                            Application.dbAsyncEachQuery
 GET     /setup                          Application.setup
 GET     /                               Application.index
+GET     /hello                          Application.hello
 

+ 7 - 7
play1/setup.py

@@ -4,16 +4,16 @@ import setup_util
 
 def start(args):
   setup_util.replace_text("play1/conf/application.conf", "jdbc:mysql:\/\/.*:3306", "jdbc:mysql://" + args.database_host + ":3306")
-  
-  subprocess.check_call("rm -rf $RESIN_HOME/webapps/*", shell=True)
-  subprocess.check_call("play1 war -o $RESIN_HOME/webapps/play1 --exclude benchmark_config", shell=True, cwd="play1")
-  subprocess.check_call("$RESIN_HOME/bin/resinctl start", shell=True)
-
+  subprocess.check_call("play1 start --%prod", shell=True, cwd="play1")
+#  subprocess.check_call("rm -rf $RESIN_HOME/webapps/*", shell=True)
+#  subprocess.check_call("play1 war -o $RESIN_HOME/webapps/play1 --exclude benchmark_config", shell=True, cwd="play1")
+#  subprocess.check_call("$RESIN_HOME/bin/resinctl start", shell=True)
   return 0
 def stop():
   try:
-    subprocess.check_call("$RESIN_HOME/bin/resinctl shutdown", shell=True)
-    subprocess.check_call("rm -rf $RESIN_HOME/webapps/*", shell=True)
+    subprocess.check_call("play1 stop", shell=True, cwd="play1")
+#    subprocess.check_call("$RESIN_HOME/bin/resinctl shutdown", shell=True)
+#    subprocess.check_call("rm -rf $RESIN_HOME/webapps/*", shell=True)
     return 0
   except subprocess.CalledProcessError:
     return 1 

+ 1 - 1
rack/README.md

@@ -12,7 +12,7 @@ The tests were run with:
 * [Ruby 2.0.0-p0](http://www.ruby-lang.org/)
 * [JRuby 1.7.3](http://jruby.org/)
 * [Rack 1.5.1](http://rack.github.com/)
-* [Passenger 3.9.5-rc3](https://www.phusionpassenger.com/)
+* [Unicorn 4.6.2](http://unicorn.bogomips.org/)
 * [Resin 4.0.34](http://www.caucho.com/)
 
 ## References

+ 1 - 1
rails-stripped/README.md

@@ -15,7 +15,7 @@ The tests were run with:
 * [Ruby 2.0.0-p0](http://www.ruby-lang.org/)
 * [JRuby 1.7.3](http://jruby.org/)
 * [Rails 3.2.11](http://rubyonrails.org/)
-* [Passenger 3.9.5-rc3](https://www.phusionpassenger.com/)
+* [Unicorn 4.6.2](http://unicorn.bogomips.org/)
 * [Resin 4.0.34](http://www.caucho.com/)
 * [MySQL 5.5.29](https://dev.mysql.com/)
 

+ 1 - 1
rails/README.md

@@ -15,7 +15,7 @@ The tests were run with:
 * [Ruby 2.0.0-p0](http://www.ruby-lang.org/)
 * [JRuby 1.7.3](http://jruby.org/)
 * [Rails 3.2.11](http://rubyonrails.org/)
-* [Passenger 3.9.5-rc3](https://www.phusionpassenger.com/)
+* [Unicorn 4.6.2](http://unicorn.bogomips.org/)
 * [Resin 4.0.34](http://www.caucho.com/)
 * [MySQL 5.5.29](https://dev.mysql.com/)
 

+ 34 - 0
ringojs-convinient/README.md

@@ -0,0 +1,34 @@
+# RingoJs Benchmarking Test
+
+This is the Ringojs with the Stick framework portion of the [benchmarking test suite](../) comparing a variety of web development platforms.
+
+### JSON Encoding Test
+
+* [JSON test controller/view](ringo-main.js)
+
+### Data-Store/Database Mapping Test
+
+* [DB test controller/model](ringo-main.js)
+
+## Infrastructure Software Versions
+
+The tests were run with:
+
+* [RingoJs v0.9](http://ringojs.org/)
+* [MySQL 5.5.29](https://dev.mysql.com/)
+
+## Test URLs
+### JSON Encoding Test
+
+http://localhost:8080/json
+
+### Data-Store/Database Mapping Test
+
+MySQL:
+
+http://localhost:8080/db
+
+### Variable Query Test
+
+MySQL:
+http://localhost:8080/db?queries=2

+ 0 - 0
ringojs-convinient/__init__.py


+ 39 - 0
ringojs-convinient/app/models.js

@@ -0,0 +1,39 @@
+var {Store, ConnectionPool, Cache} = require('ringo-sqlstore');
+
+// DO NOT TOUCH THE FOLLOWING LINE.
+// THIS VARIABLE IS REGEX REPLACED BY setup.py
+var dbHost = 'localhost';
+
+// create and configure store
+var connectionPool = module.singleton("connectionPool", function() {
+    return new ConnectionPool({
+        "url": "jdbc:mysql://" + dbHost + "/hello_world",
+        "driver": "com.mysql.jdbc.Driver",
+        "username": "benchmarkdbuser",
+        "password": "benchmarkdbpass"
+    });
+});
+var store = exports.store = new Store(connectionPool);
+var queryCache = module.singleton("queryCache", function() {
+    return new Cache(10000);
+});
+store.setQueryCache(queryCache);
+
+// define entities in DB
+exports.World = store.defineEntity('World', {
+	table: 'World',
+	properties: {
+		randomNumber: 'integer'
+	}
+});
+
+var Fortune = exports.Fortune = store.defineEntity('Fortune', {
+	table: 'Fortune',
+	properties: {
+		message: 'string'
+	}
+});
+
+Fortune.sort = function(a, b) {
+ return (a.message < b.message) ? -1 : (a.message > b.message) ? 1 : 0;
+};

+ 39 - 0
ringojs-convinient/app/views.js

@@ -0,0 +1,39 @@
+var {Application} = require("stick");
+var fs = require('fs');
+var response = require('ringo/jsgi/response');
+var models = require('./models');
+
+var {Template} = require('reinhardt/template');
+var fortuneTemplate = module.singleton('fortuneTemplate', function() {
+   return new Template(fs.read(module.resolve('../templates/fortunes.reinhardt')));
+});
+
+var app = exports.app = Application();
+app.configure("params", "route");
+
+app.get('/json', function() {
+   var helloObject = {message: "Hello, world"};
+   return response.json(helloObject);
+});
+
+app.get('/db/:queries?', function(request, queries) {
+   queries = parseInt(queries, 10) || 1;
+   var worlds = [];
+   var randId, world;
+   for (var i = 0; i < queries; i++) {
+      randId = ((Math.random() * 10000) | 0) + 1;
+      world = models.store.query('select World.* from World where World.id = :id', {id: randId})[0];
+      worlds.push(world.toJSON());
+   }
+   return response.json(worlds);
+});
+
+app.get('/fortune', function() {
+   var fortunes = models.Fortune.all();
+   fortunes.push({
+      _id: 0,
+      message: 'Additional fortune added at request time.'
+   });
+   fortunes.sort(models.Fortune.sort);
+   return response.html(fortuneTemplate.render({fortunes: fortunes}));
+});

+ 14 - 0
ringojs-convinient/benchmark_config

@@ -0,0 +1,14 @@
+{
+  "framework": "ringojs-convinient",
+  "tests": [{
+    "default": {
+      "setup_file": "setup",
+      "json_url": "/json",
+      "db_url": "/db",
+      "query_url": "/db/",
+      "fortune_url": "/fortune",
+      "port": 8080,
+      "sort": 75
+    }
+  }]
+}

+ 9 - 0
ringojs-convinient/ringo-main.js

@@ -0,0 +1,9 @@
+var {Application} = require("stick");
+
+var app = exports.app = Application();
+app.configure("mount");
+app.mount("/", require("./app/views"));
+
+if (require.main == module) {
+    require("ringo/httpserver").main(module.id);
+}

+ 28 - 0
ringojs-convinient/setup.py

@@ -0,0 +1,28 @@
+
+import subprocess
+import sys
+import setup_util
+import os
+
+def start(args):
+  setup_util.replace_text("ringojs-convinient/app/models.js", "dbHost = '.*';", "dbHost = '" + args.database_host + "';")
+
+  try:
+    subprocess.check_call("sudo mkdir -p /usr/share/ringojs/packages/ringo-sqlstore/jars/", shell=True)
+    
+    subprocess.check_call("sudo cp /usr/share/ringojs//packages/sql-ringojs-client/jars/mysql.jar /usr/share/ringojs/packages/ringo-sqlstore/jars/", shell=True)
+    subprocess.Popen("ringo --production ringo-main.js", shell=True, cwd="ringojs-convinient")
+    return 0
+  except subprocess.CalledProcessError:
+    return 1
+def stop():
+  p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
+  out, err = p.communicate()
+  for line in out.splitlines():
+    if 'ringo-main.js' in line:
+      pid = int(line.split(None, 2)[1])
+      try:
+        os.kill(pid, 9)
+      except OSError:
+        pass
+  return 0

+ 20 - 0
ringojs-convinient/templates/fortunes.reinhardt

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Fortunes</title>
+</head>
+<body>
+<table>
+<tr>
+<th>id</th>
+<th>message</th>
+</tr>
+{% for fortune in fortunes %}
+<tr>
+<td>{{fortune._id}}</td>
+<td>{{fortune.message}}</td>
+</tr>
+{% endfor %}
+</table>
+</body>
+</html>

+ 34 - 0
ringojs/README.md

@@ -0,0 +1,34 @@
+# RingoJs Benchmarking Test
+
+This is the Ringojs portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
+
+### JSON Encoding Test
+
+* [JSON test controller/view](ringo-main.js)
+
+### Data-Store/Database Mapping Test
+
+* [DB test controller/model](ringo-main.js)
+
+## Infrastructure Software Versions
+
+The tests were run with:
+
+* [RingoJs v0.9](http://ringojs.org/)
+* [MySQL 5.5.29](https://dev.mysql.com/)
+
+## Test URLs
+### JSON Encoding Test
+
+http://localhost:8080/json
+
+### Data-Store/Database Mapping Test
+
+MySQL:
+
+http://localhost:8080/db
+
+### Variable Query Test
+
+MySQL:
+http://localhost:8080/db?queries=2

+ 0 - 0
ringojs/__init__.py


+ 19 - 0
ringojs/benchmark_config

@@ -0,0 +1,19 @@
+{
+  "framework": "ringojs",
+  "tests": [{
+    "default": {
+      "setup_file": "setup",
+      "json_url": "/json",
+      "port": 8080,
+      "sort": 73
+    },
+    "raw": {
+      "setup_file": "setup",
+      "db_url": "/db",
+      "query_url": "/db?queries=",
+      "fortune_url": "/fortune",
+      "port": 8080,
+      "sort": 74
+    }
+  }]
+}

+ 11 - 0
ringojs/config/log4j.properties

@@ -0,0 +1,11 @@
+log4j.reset = true
+log4j.rootLogger = OFF
+
+log4j.appender.console = org.apache.log4j.ConsoleAppender
+log4j.appender.console.layout = org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern = %-4r [%t] %-5p %c %x - %m%n
+
+# Hint: set categories for module names you're working on to DEBUG level, e.g.:
+# log4j.category.main = DEBUG
+# log4j.category.ringo.skin = DEBUG
+# log4j.category.ringo.webapp = DEBUG

+ 91 - 0
ringojs/ringo-main.js

@@ -0,0 +1,91 @@
+var sql = require('sql-ringojs-client');
+var mustache = require('ringo/mustache');
+
+// DO NOT TOUCH THE FOLLOWING LINE.
+// THIS VARIABLE IS REGEX REPLACED BY setup.py
+var dbHost = 'localhost';
+
+var sortFortunes = function(a, b) {
+ return (a.message < b.message) ? -1 : (a.message > b.message) ? 1 : 0;
+};
+
+var fortuneTemplate = require('fs').read(module.resolve('./templates/fortune.mustache'));
+
+exports.app = function(req) {
+   var path = req.pathInfo;
+   if (path === '/json') {
+      var helloObject = {message: "Hello, world"};
+      // JSON Response Test
+      return {
+         status: 200,
+         headers: {"Content-Type": "application/json; charset=UTF-8"},
+         body: [JSON.stringify(helloObject)]
+      }
+   } else if (path === '/db') {
+      var queryCount = req.env.servletRequest.getParameter('queries');
+      try {
+         var connection = datasource.getConnection();
+         if (queryCount === null) {
+            var randId = ((Math.random() * 10000) | 0) + 1
+            var world = sql.query(connection, 'select * from World where World.id = ' + randId)[0];
+            return {
+               status: 200,
+               headers: {"Content-Type": "application/json; charset=UTF-8"},
+               body: [JSON.stringify(world)]
+            }
+         } else {
+            queryCount = parseInt(queryCount, 10);
+            var body = [];
+            var randId, world;
+            for (var i = 0; i < queryCount; i++) {
+               randId = ((Math.random() * 10000) | 0) + 1;
+               world = sql.query(connection, 'select * from World where World.id = ' + randId)[0];
+               body.push(world);
+            }
+            return {
+               status: 200,
+               headers: {"Content-Type": "application/json; charset=UTF-8"},
+               body: [JSON.stringify(body)]
+            }
+         }
+      } catch (e) {
+         connection.close();
+         connection = null;
+      } finally {
+         if (connection !== null) {
+            connection.close();
+         }
+      }
+   } else if (path === '/fortune') {
+      try {
+         var connection = datasource.getConnection();
+         var fortunes = sql.query(connection, 'select * from Fortune');
+         fortunes.push({
+            id: 0,
+            message: 'Additional fortune added at request time.'
+         });
+         fortunes.sort(sortFortunes);
+         return {
+            status: 200,
+            headers: {"Content-Type": "text/html; charset=UTF-8"},
+            body: [mustache.to_html(fortuneTemplate, {fortunes: fortunes})]
+         }
+      } catch (e) {
+         connection.close();
+         connection = null;
+      } finally {
+         if (connection !== null) {
+            connection.close();
+         }
+      }
+   }
+};
+
+
+var datasource = module.singleton('pooling-datasource', function() {
+  return sql.connect("jdbc:mysql://" + dbHost + "/hello_world", 'benchmarkdbuser', 'benchmarkdbpass');
+});
+
+if (require.main == module) {
+    require("ringo/httpserver").main(module.id);
+}

+ 25 - 0
ringojs/setup.py

@@ -0,0 +1,25 @@
+
+import subprocess
+import sys
+import setup_util
+import os
+
+def start(args):
+  setup_util.replace_text("ringojs/ringo-main.js", "dbHost = '.*';", "dbHost = '" + args.database_host + "';")
+
+  try:
+    subprocess.Popen("ringo --production ringo-main.js", shell=True, cwd="ringojs")
+    return 0
+  except subprocess.CalledProcessError:
+    return 1
+def stop():
+  p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
+  out, err = p.communicate()
+  for line in out.splitlines():
+    if 'ringo-main.js' in line:
+      pid = int(line.split(None, 2)[1])
+      try:
+        os.kill(pid, 9)
+      except OSError:
+        pass
+  return 0

+ 7 - 6
spring/src/main/webapp/WEB-INF/jsp/fortune.jsp → ringojs/templates/fortune.mustache

@@ -9,11 +9,12 @@
 <th>id</th>
 <th>message</th>
 </tr>
-<c:forEach var="o" items="${fortunes}">
+{{#fortunes}}
 <tr>
-<td>${o.id}</td>
-<td>${o.message}</td>
+<td>{{id}}</td>
+<td>{{message}}</td>
 </tr>
-</c:if>
-</table></body>
-</html>
+{{/fortunes}}
+</table>
+</body>
+</html>

+ 3 - 3
run-tests.py

@@ -14,7 +14,7 @@ parser.add_argument('-s', '--server-host', default='localhost')
 parser.add_argument('-c', '--client-host', default='localhost')
 parser.add_argument('-u', '--client-user', default='ubuntu')
 parser.add_argument('-d', '--database-host')
-parser.add_argument('-i', dest='identity_file', help='ssh key to ssh from the server instance tothe client instance.')
+parser.add_argument('-i', dest='identity_file', help='ssh key to ssh from the server instance to the client instance.')
 parser.add_argument('-p', dest='password_prompt', action='store_true')
 parser.add_argument('--install-software', action='store_true', help='runs the installation script before running the rest of the commands')
 parser.add_argument('--test', nargs='+', help='names of tests to run')
@@ -22,11 +22,11 @@ parser.add_argument('--exclude', nargs='+', help='names of tests to exclude')
 parser.add_argument('--type', choices=['all', 'json', 'db', 'query', 'fortune'], default='all', help='which type of test to run')
 parser.add_argument('-m', '--mode', choices=['benchmark', 'verify'], default='benchmark', help='verify mode will only start up the tests, curl the urls and shutdown')
 parser.add_argument('--list-tests', action='store_true', default=False, help='lists all the known tests that can run')
-parser.add_argument('--next-sort', action='store_true', default=False, help='displatys the next value that can be used as a sort value')
+parser.add_argument('--next-sort', action='store_true', default=False, help='displays the next value that can be used as a sort value')
 parser.add_argument('--max-concurrency', default=256, help='the maximum concurrency that the tests will run at. The query tests will run at this concurrency', type=int)
 parser.add_argument('--max-queries', default=20, help='The maximum number of queries to run during the query test', type=int)
 parser.add_argument('--query-interval', default=5, type=int)
-parser.add_argument('--max-threads', default=8, help='The max number of threads to run weight at, this shoul dbe set to the number of cores for your system.', type=int)
+parser.add_argument('--max-threads', default=8, help='The max number of threads to run weight at, this should be set to the number of cores for your system.', type=int)
 parser.add_argument('--duration', default=60, help='Time in seconds that each test should run for.')
 parser.add_argument('--starting-concurrency', default=8, type=int)
 parser.add_argument('--sleep', type=int, default=60, help='the amount of time to sleep after starting each test to allow the server to start up.')

+ 1 - 1
sinatra/README.md

@@ -14,7 +14,7 @@ The tests were run with:
 * [Ruby 2.0.0-p0](http://www.ruby-lang.org/)
 * [JRuby 1.7.3](http://jruby.org/)
 * [Sinatra 1.3.4](http://www.sinatrarb.com/)
-* [Passenger 3.9.5-rc3](https://www.phusionpassenger.com/)
+* [Unicorn 4.6.2](http://unicorn.bogomips.org/)
 * [Resin 4.0.34](http://www.caucho.com/)
 * [MySQL 5.5.29](https://dev.mysql.com/)
 

+ 2 - 1
spring/benchmark_config

@@ -6,8 +6,9 @@
       "json_url": "/spring/json",
       "db_url": "/spring/db",
       "query_url": "/spring/db?queries=",
+      "fortune_url": "/spring/fortunes",
       "port": 8080,
       "sort": 22
     }
   }]
-}
+}

+ 15 - 0
spring/src/main/java/hello/domain/Fortune.java

@@ -13,12 +13,27 @@ public class Fortune
   public int id;
   public String message;
   
+  public Fortune()
+  {
+
+  }
+  
   public Fortune(int id, String message)
   {
     this.id = id;
     this.message = message;
   }
   
+  public int getId()
+  {
+    return this.id;
+  }
+
+  public String getMessage()
+  {
+    return this.message;
+  }
+
   /**
    * For our purposes, Fortunes sort by their message text. 
    */

+ 13 - 10
spring/src/main/java/hello/web/HelloFortuneController.java

@@ -23,19 +23,22 @@ import org.springframework.web.servlet.ModelAndView;
 public class HelloFortuneController
 {
 
-  private static final int    DB_ROWS                = 10000;
-
-  @RequestMapping(value = "/fortune")
+  @RequestMapping(value = "/fortunes")
   public ModelAndView fortunes()
   {
     
     final Session session = HibernateUtil.getSessionFactory().openSession();
-    List<Fortune> fortunes = (List<Fortune>)session.createCriteria(Fortune.class).list()
-    session.close();
-    
-    fortunes.add(new Fortune(0, "Additional fortune added at request time."));
-    Collections.sort(fortunes);
-
-    return new ModelAndView("fortunes", "command", fortunes);
+    try
+    {
+      List fortunes = new ArrayList(session.createCriteria(Fortune.class).list());
+      fortunes.add(new Fortune(0, "Additional fortune added at request time."));
+      Collections.sort(fortunes);
+
+      return new ModelAndView("fortunes", "fortunes", fortunes);
+    }
+    finally
+    {
+      session.close();
+    }
   }
 }

+ 1 - 0
spring/src/main/resources/hibernate.cfg.xml

@@ -14,5 +14,6 @@
         <property name="hibernate.current_session_context_class">thread</property>
 
         <mapping class="hello.domain.World" />
+        <mapping class="hello.domain.Fortune" />
     </session-factory>
 </hibernate-configuration>

+ 22 - 0
spring/src/main/webapp/WEB-INF/jsp/fortunes.jsp

@@ -0,0 +1,22 @@
+<%@page contentType="text/html" pageEncoding="UTF-8"%>
+<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
+<!DOCTYPE html>
+<html>
+<head>
+<title>Fortunes</title>
+</head>
+<body>
+<table>
+<tr>
+<th>id</th>
+<th>message</th>
+</tr>
+<c:forEach var="o" items="${fortunes}">
+<tr>
+<td>${o.getId()}</td>
+<td><spring:escapeBody htmlEscape="true">${o.getMessage()}</spring:escapeBody></body></td>
+</tr>
+</c:forEach>
+</table>
+</html>

+ 4 - 3
tornado/deploy/nginx.conf

@@ -1,11 +1,12 @@
 #user nginx;
-worker_processes 1;
+worker_processes 8;
 
 #error_log /var/log/nginx/error.log;
 #pid /var/run/nginx.pid;
 
 events {
-    worker_connections 1024;
+    worker_connections 8196;
+    accept_mutex off;
     use epoll;
 }
 
@@ -27,7 +28,7 @@ http {
 
     # access_log /var/log/nginx/access.log;
 
-    keepalive_timeout 65;
+    keepalive_timeout 5;
     proxy_read_timeout 200;
     sendfile on;
     tcp_nopush on;