Browse Source

Merge branch '797'

Alex Schneider 11 years ago
parent
commit
4696b5d48d
5 changed files with 133 additions and 76 deletions
  1. 7 13
      mojolicious/README.md
  2. 102 30
      mojolicious/app.pl
  3. 11 24
      mojolicious/benchmark_config
  4. 12 8
      mojolicious/setup.py
  5. 1 1
      toolset/setup/linux/languages/perl.sh

+ 7 - 13
mojolicious/README.md

@@ -1,20 +1,15 @@
 # Setup
 # Setup
 
 
 * Perl 5.16.3
 * Perl 5.16.3
-* MySQL 5.5
+* MongoDB 2.4.9
 * Wrk 2.0
 * Wrk 2.0
 
 
 # Requirements
 # Requirements
 
 
 * Mojolicious
 * Mojolicious
+* Mango
 * JSON::XS
 * JSON::XS
-* DBI
-* 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
+* Hypnotoad provided by Mojolicious
 
 
 # Deployment
 # Deployment
 
 
@@ -22,12 +17,11 @@ Set production mode:
 
 
     export MOJO_MODE=production
     export MOJO_MODE=production
 
 
-Something along the lines of
+Start with Mojolicious' non-blocking preforking server
 
 
-    plackup -s Starman --workers=8 -l /tmp/frameworks-benchmark.sock -a ./app.pl
+    hypnotoad app.pl
 
 
-if you want to front it with nginx, otherwise
+To stop again, simply run
 
 
-    plackup -s Starman --port 8080 --workers=8 -a ./app.pl
+    hypnotoad -s app.pl
 
 
-or the equivalent Morbo or Hypnotoad commands.

+ 102 - 30
mojolicious/app.pl

@@ -1,39 +1,111 @@
-#!/usr/bin/env perl
 use Mojolicious::Lite;
 use Mojolicious::Lite;
-use JSON::XS;
-use Memoize;
-use DBI;
+use Mango;
 
 
-my $dsn = "dbi:mysql:database=hello_world;host=localhost;port=3306";
-my $dbh = DBI->connect( $dsn, 'benchmarkdbuser', 'benchmarkdbpass', {} );
-my $sth = $dbh->prepare("SELECT * FROM World where id = ?");
+use JSON::XS 'encode_json';
+use Scalar::Util 'looks_like_number';
 
 
+# configuration
 
 
-get '/json' => sub {
-    my $self = shift;    
-    $self->render( text => JSON::XS::encode_json( { message => 'Hello, world!' } ), format => 'json' );
+plugin JSONConfig => {
+  file => 'app.conf',
+  default => {
+    database_host => 'localhost',
+    workers => 8,
+  },
 };
 };
 
 
-get '/db' => sub {
-    my $self = shift;
-    my $queries = $self->param('queries') || 1;
-    my @response;
-    for ( 1 .. $queries ) {
-        my $id = int rand 10000 + 1;
-        $sth->execute($id);
-        if ( my $row = $sth->fetchrow_hashref ) {
-            if ( $queries == 1 ) {
-                $self->render( json => { id => $id, randomNumber => $row->{randomNumber} } );
-            }
-            else {
-                push @response,
-                  { id => $id, randomNumber => $row->{randomNumber} };
-            }
-        }
-    }
-    if ( $queries > 1 ) {
-        $self->render( json => \@response );
-    }
+app->config->{hypnotoad}{workers} = app->config->{workers};
+
+# Database connections
+
+helper mango   => sub { state $mango = Mango->new('mongodb://'. shift->config->{database_host} . ':27017') };
+helper db      => sub { state $db = shift->mango->db('hello_world') };
+helper world   => sub { shift->db->collection('World') };
+helper fortune => sub { shift->db->collection('Fortune') };
+
+# JSON::XS renderer
+
+helper render_json => sub { shift->render( data => encode_json(shift), format => 'json' ) }; 
+
+# Routes
+
+get '/json' => sub { shift->render_json({message => 'Hello, World!'}) };
+
+get '/db' => sub { shift->render_query(1) };
+
+get '/queries' => sub {
+  my $c = shift;
+  $c->render_query($c->param('queries'));
+};
+
+get '/fortunes' => sub {
+  my $c = shift->render_later;
+  my $tx = $c->tx;
+  $c->fortune->find->all(sub{
+    my ($cursor, $err, $docs) = @_;
+    push @$docs, { _id => 0, message => 'Additional fortune added at request time.' };
+    $c->render( fortunes => docs => $docs ) unless $tx->is_finished;
+  });
+};
+
+get '/updates' => sub {
+  my $c = shift;
+  $c->render_query($c->param('queries'), 1);
+};
+
+get '/plaintext' => sub { shift->render( text => 'Hello, World!' ) };
+
+# Additional helpers (shared code)
+
+helper 'render_query' => sub {
+  my ($self, $q, $update) = @_;
+  $self->render_later;
+
+  $q = 1 unless looks_like_number($q);
+  $q = 500 if $q > 500;
+
+  my $r  = [];
+  my $tx = $self->tx;
+
+  my $delay = Mojo::IOLoop->delay;
+  $delay->on(finish => sub{
+    $self->render_json($r) unless $tx->is_finished;
+  });
+
+  my $world = $self->world;
+
+  foreach (1 .. $q) {
+    my $id = int rand 10_000;
+    my $end = $delay->begin;
+    $world->find_one({_id => $id} => sub {
+      my ($world, $err, $doc) = @_;
+      if ($update) { $doc->{randomNumber} = 1 + int rand 10_000 };
+      push @$r, { id => $id, randomNumber => $doc->{randomNumber} };
+      $update ? $world->save($doc, $end) : $end->();
+    });
+  }
+
+  # use this line if not running under a Mojolicious server
+  # $delay->wait unless $delay->ioloop->is_running;
 };
 };
 
 
 app->start;
 app->start;
+
+__DATA__
+
+@@ fortunes.html.ep
+<!DOCTYPE html>
+<html>
+  <head><title>Fortunes</title></head>
+  <body>
+    <table>
+      <tr><th>id</th><th>message</th></tr>
+      % foreach my $doc (sort { $a->{message} cmp $b->{message} } @$docs) {
+        <tr>
+          <td><%= $doc->{_id}     %></td>
+          <td><%= $doc->{message} %></td>
+        </tr>
+      % }
+    </table>
+  </body>
+</html>

+ 11 - 24
mojolicious/benchmark_config

@@ -4,39 +4,26 @@
     "default": {
     "default": {
       "setup_file": "setup",
       "setup_file": "setup",
       "json_url": "/json",
       "json_url": "/json",
-      "port": 8080,
-      "approach": "Realistic",
-      "classification": "Fullstack",
-      "database": "None",
-      "framework": "mojolicious",
-      "language": "Perl",
-      "orm": "Full",
-      "platform": "Plack",
-      "webserver": "Starman",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "mojolicious",
-      "notes": "",
-      "versus": ""
-    },
-    "raw": {
-      "setup_file": "setup",
       "db_url": "/db",
       "db_url": "/db",
-      "query_url": "/db?queries=",
+      "query_url": "/queries",
+      "fortune_url": "/fortunes",
+      "update_url": "/updates",
+      "plaintext_url": "/plaintext",
       "port": 8080,
       "port": 8080,
       "approach": "Realistic",
       "approach": "Realistic",
-      "classification": "Fullstack",
-      "database": "MySQL",
+      "classification": "Full",
+      "database": "MongoDB",
       "framework": "mojolicious",
       "framework": "mojolicious",
       "language": "Perl",
       "language": "Perl",
       "orm": "Raw",
       "orm": "Raw",
-      "platform": "Plack",
-      "webserver": "Starman",
+      "platform": "Mojolicious",
+      "webserver": "Hypnotoad",
       "os": "Linux",
       "os": "Linux",
       "database_os": "Linux",
       "database_os": "Linux",
-      "display_name": "mojolicious",
+      "display_name": "Mojolicious",
       "notes": "",
       "notes": "",
       "versus": ""
       "versus": ""
     }
     }
   }]
   }]
-}
+}
+

+ 12 - 8
mojolicious/setup.py

@@ -1,6 +1,6 @@
 import subprocess
 import subprocess
 import sys
 import sys
-import setup_util
+import json
 from os.path import expanduser
 from os.path import expanduser
 import os
 import os
 import getpass
 import getpass
@@ -8,23 +8,27 @@ import getpass
 home = expanduser("~")
 home = expanduser("~")
 
 
 def start(args, logfile, errfile):
 def start(args, logfile, errfile):
-  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")
+  conf = { 
+    'database_host' : args.database_host,
+    'workers'       : args.max_threads,
+  }
+  with open('mojolicious/app.conf', 'w') as f:
+    f.write(json.dumps(conf))
 
 
   try:
   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", stderr=errfile, stdout=logfile)
-    subprocess.check_call("sudo /usr/local/nginx/sbin/nginx -c " + home + "/FrameworkBenchmarks/mojolicious/nginx.conf", shell=True, stderr=errfile, stdout=logfile)
+    # os.environ["MOJO_MODE"] = "production"
+    subprocess.Popen("hypnotoad ./app.pl", shell=True, cwd="mojolicious", 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.call("sudo /usr/local/nginx/sbin/nginx -s stop", shell=True, stderr=errfile, stdout=logfile)
+    subprocess.call("hypnotoad -s ./app.pl", shell=True, cwd="mojolicious", stderr=errfile, stdout=logfile)
     p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
     p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
     out, err = p.communicate()
     out, err = p.communicate()
     for line in out.splitlines():
     for line in out.splitlines():
-      if 'starman' in line:
+      if 'hypnotoad' in line:
         pid = int(line.split(None, 2)[1])
         pid = int(line.split(None, 2)[1])
         os.kill(pid, 15)
         os.kill(pid, 15)
     return 0
     return 0

+ 1 - 1
toolset/setup/linux/languages/perl.sh

@@ -8,4 +8,4 @@ perl perl-build.pl -DDEBUGGING=-g 5.18.2 perl-5.18
 
 
 fw_get http://cpanmin.us -O cpanminus.pl
 fw_get http://cpanmin.us -O cpanminus.pl
 perl-5.18/bin/perl cpanminus.pl --notest --no-man-page App::cpanminus
 perl-5.18/bin/perl cpanminus.pl --notest --no-man-page App::cpanminus
-perl-5.18/bin/cpanm -f --notest --no-man-page DBI DBD::mysql Kelp Dancer Mojolicious Kelp::Module::JSON::XS Dancer::Plugin::Database Starman Plack JSON Web::Simple DBD::Pg JSON::XS EV HTTP::Parser::XS Monoceros EV IO::Socket::IP IO::Socket::SSL Memoize
+perl-5.18/bin/cpanm -f --notest --no-man-page DBI DBD::mysql Kelp Dancer Mojolicious Mango Kelp::Module::JSON::XS Dancer::Plugin::Database Starman Plack JSON Web::Simple DBD::Pg JSON::XS EV HTTP::Parser::XS Monoceros EV IO::Socket::IP IO::Socket::SSL Memoize