Browse Source

Merge pull request #866 from kazeburo/master

Plack: change to use Starlet and optimize app
mcocciaTE 11 years ago
parent
commit
5575b1ed24
7 changed files with 80 additions and 26 deletions
  1. 3 5
      plack/README.md
  2. 24 14
      plack/app.psgi
  3. 2 2
      plack/benchmark_config
  4. 6 1
      plack/cpanfile
  5. 31 0
      plack/nginx.conf
  6. 12 4
      plack/setup.py
  7. 2 0
      plack/source_code

+ 3 - 5
plack/README.md

@@ -11,8 +11,7 @@ Plack
 # Requirements
 # Requirements
 
 
 * Plack
 * Plack
-* Monoceros or Starman
-* EV
+* Starlet
 * HTTP::Parser::XS
 * HTTP::Parser::XS
 * JSON::XS
 * JSON::XS
 * DBI
 * DBI
@@ -20,6 +19,5 @@ Plack
 
 
 # Deployment
 # Deployment
 
 
-    plackup -E production -s Starman --workers=2 -l :8080 app.psgi
-    - or -
-    plackup -E production -s Monoceros --max-workers=2 -l :8080 app.psgi
+    plackup -E production -s Starlet --max-keepalive-reqs 5000 \
+      --max-reqs-per-child 50000 --min-reqs-per-child 40000 --workers=2 -l :8080 app.psgi

+ 24 - 14
plack/app.psgi

@@ -1,24 +1,34 @@
+use strict;
 use v5.16;
 use v5.16;
-use Plack::Builder;
-use Plack::Request;
-use JSON::XS 'encode_json';
+use utf8;
+use JSON::XS qw(encode_json);
 use DBI;
 use DBI;
 
 
 my $dbh = DBI->connect_cached(
 my $dbh = DBI->connect_cached(
     'dbi:mysql:database=hello_world;host=localhost;port=3306', 
     'dbi:mysql:database=hello_world;host=localhost;port=3306', 
-    qw(benchmarkdbuser benchmarkdbpass)
+    'benchmarkdbuser',
+    'benchmarkdbpass',
+    { AutoInactiveDestroy => 1, mysql_enable_utf8 => 1 }
 ) || die $!;
 ) || die $!;
 
 
-my $sth = $dbh->prepare_cached('SELECT randomNumber FROM World WHERE id = ?');
+my $query = 'SELECT id, randomNumber FROM World WHERE id = ?';
 my $header = [qw(Content-Type application/json)];
 my $header = [qw(Content-Type application/json)];
+my $message = { message => 'Hello, World!' };
 
 
-builder {
-    mount '/json' => sub { [ 200, $header, [ encode_json({ message => 'Hello, World!' })] ] },
-    mount '/db' => sub {
-        my @rs = 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;
-        [ 200, $header, [ encode_json( @rs > 1 ? \@rs : $rs[0] ) ] ] } };
+my $app = sub {
+    my $env = shift;
+    if ( $env->{PATH_INFO} eq '/json' ) {
+        return [ 200, $header, [ encode_json($message) ]];
+    }
+    elsif ( $env->{PATH_INFO} eq '/db' ) {
+        my ($n) = ($env->{QUERY_STRING} || "" ) =~ m!queries=(\d+)!;
+        $n //= 1;
+        my @rs = map {{id=>$_->[0]+0,randomNumber=>$_->[1]+0}} 
+            map { $dbh->selectrow_arrayref($query,{},int rand 10000 + 1) } 1..$n;
+        return [ 200, $header, [ '{}' ]] unless @rs;
+        return [ 200, $header, [ encode_json( @rs > 1 ? \@rs : $rs[0] ) ]];
+    }
+    [ 404, [], ['not found']];
+};
 
 
+$app;

+ 2 - 2
plack/benchmark_config

@@ -12,8 +12,8 @@
       "framework": "plack",
       "framework": "plack",
       "language": "Perl",
       "language": "Perl",
       "orm": "Raw",
       "orm": "Raw",
-      "platform": "Plack",
-      "webserver": "Starman",
+      "platform": "Starlet",
+      "webserver": "nginx",
       "os": "Linux",
       "os": "Linux",
       "database_os": "Linux",
       "database_os": "Linux",
       "display_name": "plack",
       "display_name": "plack",

+ 6 - 1
plack/cpanfile

@@ -1 +1,6 @@
-map requires($_), qw(JSON::XS EV HTTP::Parser::XS Plack DBI DBD::mysql DBI Monoceros Starman);
+requires 'JSON::XS', '3.01';
+requires 'HTTP::Parser::XS', '0.16';
+requires 'Plack', '1.0030';
+requires 'DBI', '1.631';
+requires 'DBD::mysql', '4.027';
+requires 'Starlet', '0.24';

+ 31 - 0
plack/nginx.conf

@@ -0,0 +1,31 @@
+error_log stderr error;
+pid        /tmp/nginx.pid;
+worker_processes 4;
+
+events {
+  worker_connections  4096;
+  multi_accept on;
+}
+
+http {
+  access_log       off;
+  tcp_nodelay      on;
+  keepalive_requests 50000;
+  etag off;
+
+  upstream backendurl {
+    server unix:/home/tfb/FrameworkBenchmarks/plack/app.sock;
+    keepalive 8;
+  }
+
+  server {
+    listen 8080;
+    server_name localhost;
+    location / {
+      proxy_http_version 1.1;
+      proxy_set_header Connection "";
+      proxy_pass http://backendurl;
+    }
+  }
+}
+

+ 12 - 4
plack/setup.py

@@ -1,21 +1,29 @@
 import subprocess
 import subprocess
 import sys
 import sys
 import setup_util
 import setup_util
+from os.path import expanduser
 import os
 import os
+import getpass
+
+home = expanduser("~")
 
 
 def start(args, logfile, errfile):
 def start(args, logfile, errfile):
   setup_util.replace_text("plack/app.psgi", "localhost", ""+ args.database_host +"")
   setup_util.replace_text("plack/app.psgi", "localhost", ""+ args.database_host +"")
+  setup_util.replace_text("plack/nginx.conf", "USR", getpass.getuser())
+  setup_util.replace_text("plack/nginx.conf", "server unix:.*\/FrameworkBenchmarks", "server unix:" + home + "/FrameworkBenchmarks")
   try:
   try:
     subprocess.check_call("curl -L http://cpanmin.us | perl - App::cpanminus", shell=True, cwd="plack", stderr=errfile, stdout=logfile)
     subprocess.check_call("curl -L http://cpanmin.us | perl - App::cpanminus", shell=True, cwd="plack", stderr=errfile, stdout=logfile)
-    subprocess.check_call("cpanm --installdeps .", shell=True, cwd="plack", stderr=errfile, stdout=logfile)
-    pid = subprocess.Popen("plackup -E production -s Monoceros -l :8080 --max-workers=" + str(args.max_threads) + " app.psgi", shell=True, cwd="plack", stderr=errfile, stdout=logfile).pid
-    open('plack/app.pid', 'w').write(str(pid))
+    subprocess.check_call("cpanm --notest --no-man-pages --installdeps "+home+"/FrameworkBenchmarks/plack", shell=True, cwd="plack", stderr=errfile, stdout=logfile)
+    subprocess.Popen("start_server --backlog=16384 --pid-file="+home+"/FrameworkBenchmarks/plack/app.pid --path="+home+"/FrameworkBenchmarks/plack/app.sock -- plackup -E production -s Starlet --max-keepalive-reqs 1000 --max-reqs-per-child 50000 --min-reqs-per-child 40000 --max-workers=" + str(args.max_threads+4) + " -a "+home+"/FrameworkBenchmarks/plack/app.psgi", shell=True, cwd="plack", stderr=errfile, stdout=logfile)
+    subprocess.check_call("/usr/local/nginx/sbin/nginx -c " + home + "/FrameworkBenchmarks/plack/nginx.conf", shell=True,stderr=errfile, stdout=logfile)
     return 0
     return 0
   except subprocess.CalledProcessError:
   except subprocess.CalledProcessError:
     return 1
     return 1
 def stop(logfile, errfile):
 def stop(logfile, errfile):
   try:
   try:
-    subprocess.Popen("kill -TERM $(ps --ppid `cat app.pid` -o pid --no-header)", shell=True, cwd="plack", stderr=errfile, stdout=logfile)
+    subprocess.call('kill -TERM $(cat '+home+"/FrameworkBenchmarks/plack/app.pid)", shell=True, stderr=errfile, stdout=logfile)
+    subprocess.call("/usr/local/nginx/sbin/nginx -c " + home + "/FrameworkBenchmarks/plack/nginx.conf -s stop", shell=True, stderr=errfile, stdout=logfile)
     return 0
     return 0
   except subprocess.CalledProcessError:
   except subprocess.CalledProcessError:
     return 1
     return 1
+

+ 2 - 0
plack/source_code

@@ -1,2 +1,4 @@
 ./plack/app.psgi
 ./plack/app.psgi
 ./plack/cpanfile
 ./plack/cpanfile
+./plack/nginx.conf
+