PSGI and Plack
     Tatsuhiko Miyagawa
 London Perl Workshop 2009
Tatsuhiko Miyagawa

• Japanese, lives in San Francisco
• Works at Six Apart
• 170+ CPAN modules (id:MIYAGAWA)
• @miyagawa
...
Background
Web Frameworks
Maypole Mason Mojo Sledge Catalyst Spoon PageKit
 AxKit Egg Gantry Continuity Solstice Mojolicious
Tripletail Konstrukt Re...
Most of them run on
 mod_perl and CGI
Some run on FastCGI
Some run standalone
Very few supports
  non-blocking
Because:
No common server
environment layers
CGI.pm
Runs “fine” on:
    CGI, FastCGI, mod_perl (1 & 2)
Standalone (with HTTP::Server::Simple)
CGI.pm = LCD
   It’s also Perl core
Catalyst
The most popular framework as of today
Catalyst::Engine::*
            Server abstractions.
Well supported Apache, FCGI and Standalone
                No CGI.pm
CGI.pm
  Jifty, CGI::Application, Spoon


mod_perl centric
Mason, Sledge, PageKit, WebGUI


       Adapters
  Catalyst, Ma...
Problems:
       Duplicated efforts
No fair performance evaluations
Question:
 Can we share
those adapters?
Answer:
HTTP::Engine
HTTP::Engine
Lots of adapters (FCGI, Apache2, POE)
     Clean Request/Response API
Written by Yappo, tokuhirom and others
Problems
Mo[ou]se everywhere
 Mouse is light but still overspec for some env.
Monolithic
All implementations share HTTP::Engine roles
and builders, which is sometimes hard to adapt
      and has less ...
APIs everywhere
Most frameworks have their request/response API
          Sometimes there are gaps.
    Annoying to write ...
Solution
Steal good stuff
from Python/Ruby
WSGI (Python)
   Rack
WSGI (PEP-333)
mod_wsgi, Paste, AppEngine
 Django, CherryPy, Pylons
Rack
Passenger, thin, Unicorn, Heroku
      Rails, Merb, Sinatra
WSGI/Rack
 Completely separate interface
from the actual implementation
Approach
Split HTTP::Engine
 into three parts
Interface
Implementations
    Utilities
PSGI (interface)
Plack::Server (implementations)
      Plack::* (utilities)
Who’s on board
Benjamin Trott, Yuval Kogman, Stevan Little, Shawn M
 Moore, Mark Stosberg, Matt S Trout, Jesse Vincent,
  ...
PSGI
Perl Web Server Gateway Interface
Interface
WARNING
You DON’T need to care about these
 interface details as an app developer.
my $app = sub {
   my $env = shift;
   # ...
   return [ $status, $header, $body ];
};
PSGI application
   code reference
   $app = sub {...};
my $app = sub {
   my $env = shift;
   # ...
   return [ $status, $header, $body ];
};
environment hash
$env: CGI-like env variables
+ psgi.input, psgi.errors etc.
my $app = sub {
   my $env = shift;
   # ...
   return [ $status, $header, $body ];
};
Response
 array ref with three elements
status code, headers (array ref)
and body (IO-like or array ref)
my $app = sub {
   my $env = shift;
   # ...
   return [ $status, $header, $body ];
};
$body
  IO::Handle-like
getline() and close()
IO::Handle-like
       We really envy Python/Ruby
          for built-in iterators
(Perl’s filehandle is also an object, bu...
WARNING
You DON’T need to care about these
 interface details as an app developer.
              Becuase ...
Frameworks
Write an adapter to return
 PSGI application code ref.
(and forget about servers!)
Framework Adapters
  CGI::Application, Catalyst, Maypole
Mason, Squatting, Mojo, HTTP::Engine etc.
Applications
MT::App, WebGUI
use Foo; # is a Catalyst application
Foo->setup_engine(‘PSGI’);
my $app = sub { Foo->run };
Servers
   Set up $env, run the app
and emits response out of $res
Plack
namespace for servers and utilities
Plack::Server
 reference server implementations
  Standalone, FCGI, Apache2, CGI
Standalone, Prefork, AnyEvent, Coro
Very fast
 5000 QPS on standalone
15000 QPS with prefork :)
Utilities
Plackup
Run PSGI app instantly from CLI
     (inspired by rackup)
DEMO
Middleware
my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

my $mw = sub {
   my $env = shift;
   # do ...
Middleware
Static, AccessLog, ConditionalGET
 ErrorDocument, StackTrace etc.
Plack::Middleware
  reusable and extensible
  Middleware framework
 Plack::Builder DSL in .psgi
my $app = sub {
   return [ $status, $header, $body ];
};

use Plack::Builder;

builder {
  enable “Static”, root => “/htd...
Plack::App::URLMap
    Multiplex multiple apps
 Integrated with Builder DSL
use CatApp;
use CGIApp;

my $c1 = sub { CatApp->run };
my $c2 = sub { CGIApp->run_psgi };

use Plack::Builder;

builder {
...
CGI::PSGI
Easy migration from CGI.pm
CGI::Emulate::PSGI
    CGI::Compile
Easiest migration from CGI scripts (like Registry)
Plack::Request
    like libapreq (Apache::Request)
wrapper APIs for framework developers
use Plack::Request;

my $app = sub {
 my $req = Plack::Request->new(shift);

 my $body = “Hello “ . $req->param(‘n’);
 my ...
Plack::Test
 Unified interface to write tests
with Mock HTTP and Live HTTP
use Plack::Test;
use HTTP::Request::Common;

my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};...
use Plack::Test;
use HTTP::Request::Common;
$Plack::Test::Impl = “Server”;

my $app = sub {
   my $env = shift;
   return ...
Streaming
event loop / long-poll
# Pull streaming for blocking server
use IO::Handle::Util qw(io_from_getline);

my $app = sub {
   my $env = shift;
   my ...
# Push streaming for non-blocking server
use AnyEvent;
use JSON;

my $app = sub {
  my $env = shift;
  return sub {
    my...
Non-blocking servers
AnyEvent, Coro, POE, Danga::Socket
Non-blocking framework
           Tatsumaki
  http://github.com/miyagawa/Tatsumaki
Other Servers
nginx embedded perl
 http://github.com/yappo/nginx-psgi-patchs
mod_psgi
http://github.com/spiritloose/mod_psgi
evpsgi
http://github.com/sekimura/evpsgi
Perlbal plugin
http://github.com/miyagawa/Perlbal-Plugin-PSGI
Cloud
WSGI (PEP-333)
mod_wsgi, Paste, AppEngine
 Django, CherryPy, Pylons
Rack
Passenger, Thin, Unicorn, Heroku
      Rails, Merb, Sinatra
What if GAE Perl
comes with PSGI ...
Summary

• PSGI is an interface, Plack is the code.
• We have many (pretty fast) servers.
• We have adapters and tools for...
http://github.com/miyagawa/Plack
          http://plackperl.org/
http://advent.plackperl.org/ ←NEW!
        irc://irc.perl...
Questions?
Plack - LPW 2009
Plack - LPW 2009
Plack - LPW 2009
Upcoming SlideShare
Loading in...5
×

Plack - LPW 2009

3,650

Published on

Published in: Technology
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,650
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
23
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide
  • Plack - LPW 2009

    1. 1. PSGI and Plack Tatsuhiko Miyagawa London Perl Workshop 2009
    2. 2. Tatsuhiko Miyagawa • Japanese, lives in San Francisco • Works at Six Apart • 170+ CPAN modules (id:MIYAGAWA) • @miyagawa • bulknews.typepad.com
    3. 3. Background
    4. 4. Web Frameworks
    5. 5. Maypole Mason Mojo Sledge Catalyst Spoon PageKit AxKit Egg Gantry Continuity Solstice Mojolicious Tripletail Konstrukt Reaction Jifty Cyclone3 WebGUI OpenInteract Squatting Dancer CGI::Application Nanoa Ark Angelos Noe Schenker Tatsumaki Web::Simple Apache2::REST SweetPea Hydrant
    6. 6. Most of them run on mod_perl and CGI
    7. 7. Some run on FastCGI
    8. 8. Some run standalone
    9. 9. Very few supports non-blocking
    10. 10. Because:
    11. 11. No common server environment layers
    12. 12. CGI.pm
    13. 13. Runs “fine” on: CGI, FastCGI, mod_perl (1 & 2) Standalone (with HTTP::Server::Simple)
    14. 14. CGI.pm = LCD It’s also Perl core
    15. 15. Catalyst The most popular framework as of today
    16. 16. Catalyst::Engine::* Server abstractions. Well supported Apache, FCGI and Standalone No CGI.pm
    17. 17. CGI.pm Jifty, CGI::Application, Spoon mod_perl centric Mason, Sledge, PageKit, WebGUI Adapters Catalyst, Maypole, Squatting
    18. 18. Problems: Duplicated efforts No fair performance evaluations
    19. 19. Question: Can we share those adapters?
    20. 20. Answer: HTTP::Engine
    21. 21. HTTP::Engine Lots of adapters (FCGI, Apache2, POE) Clean Request/Response API Written by Yappo, tokuhirom and others
    22. 22. Problems
    23. 23. Mo[ou]se everywhere Mouse is light but still overspec for some env.
    24. 24. Monolithic All implementations share HTTP::Engine roles and builders, which is sometimes hard to adapt and has less place for optimizations.
    25. 25. APIs everywhere Most frameworks have their request/response API Sometimes there are gaps. Annoying to write bridges and wrappers
    26. 26. Solution
    27. 27. Steal good stuff from Python/Ruby
    28. 28. WSGI (Python) Rack
    29. 29. WSGI (PEP-333) mod_wsgi, Paste, AppEngine Django, CherryPy, Pylons
    30. 30. Rack Passenger, thin, Unicorn, Heroku Rails, Merb, Sinatra
    31. 31. WSGI/Rack Completely separate interface from the actual implementation
    32. 32. Approach Split HTTP::Engine into three parts
    33. 33. Interface Implementations Utilities
    34. 34. PSGI (interface) Plack::Server (implementations) Plack::* (utilities)
    35. 35. Who’s on board Benjamin Trott, Yuval Kogman, Stevan Little, Shawn M Moore, Mark Stosberg, Matt S Trout, Jesse Vincent, Chia-liang Kao, Dave Rolsky, John Beppu ...
    36. 36. PSGI Perl Web Server Gateway Interface
    37. 37. Interface
    38. 38. WARNING You DON’T need to care about these interface details as an app developer.
    39. 39. my $app = sub { my $env = shift; # ... return [ $status, $header, $body ]; };
    40. 40. PSGI application code reference $app = sub {...};
    41. 41. my $app = sub { my $env = shift; # ... return [ $status, $header, $body ]; };
    42. 42. environment hash $env: CGI-like env variables + psgi.input, psgi.errors etc.
    43. 43. my $app = sub { my $env = shift; # ... return [ $status, $header, $body ]; };
    44. 44. Response array ref with three elements status code, headers (array ref) and body (IO-like or array ref)
    45. 45. my $app = sub { my $env = shift; # ... return [ $status, $header, $body ]; };
    46. 46. $body IO::Handle-like getline() and close()
    47. 47. IO::Handle-like We really envy Python/Ruby for built-in iterators (Perl’s filehandle is also an object, but it really sucks)
    48. 48. WARNING You DON’T need to care about these interface details as an app developer. Becuase ...
    49. 49. Frameworks Write an adapter to return PSGI application code ref. (and forget about servers!)
    50. 50. Framework Adapters CGI::Application, Catalyst, Maypole Mason, Squatting, Mojo, HTTP::Engine etc.
    51. 51. Applications MT::App, WebGUI
    52. 52. use Foo; # is a Catalyst application Foo->setup_engine(‘PSGI’); my $app = sub { Foo->run };
    53. 53. Servers Set up $env, run the app and emits response out of $res
    54. 54. Plack namespace for servers and utilities
    55. 55. Plack::Server reference server implementations Standalone, FCGI, Apache2, CGI Standalone, Prefork, AnyEvent, Coro
    56. 56. Very fast 5000 QPS on standalone 15000 QPS with prefork :)
    57. 57. Utilities
    58. 58. Plackup Run PSGI app instantly from CLI (inspired by rackup)
    59. 59. DEMO
    60. 60. Middleware
    61. 61. my $app = sub { my $env = shift; return [ $status, $header, $body ]; }; my $mw = sub { my $env = shift; # do something with $env my $res = $app->($env); # do something with $res; return $res; };
    62. 62. Middleware Static, AccessLog, ConditionalGET ErrorDocument, StackTrace etc.
    63. 63. Plack::Middleware reusable and extensible Middleware framework Plack::Builder DSL in .psgi
    64. 64. my $app = sub { return [ $status, $header, $body ]; }; use Plack::Builder; builder { enable “Static”, root => “/htdocs”, path => qr!^/static/!; enable “Deflater”; # gzip/deflate $app; }
    65. 65. Plack::App::URLMap Multiplex multiple apps Integrated with Builder DSL
    66. 66. use CatApp; use CGIApp; my $c1 = sub { CatApp->run }; my $c2 = sub { CGIApp->run_psgi }; use Plack::Builder; builder { mount “/cat” => $c1; mount “/cgi-app” => builder { enable “StackTrace”; $c2; }; }
    67. 67. CGI::PSGI Easy migration from CGI.pm
    68. 68. CGI::Emulate::PSGI CGI::Compile Easiest migration from CGI scripts (like Registry)
    69. 69. Plack::Request like libapreq (Apache::Request) wrapper APIs for framework developers
    70. 70. use Plack::Request; my $app = sub { my $req = Plack::Request->new(shift); my $body = “Hello “ . $req->param(‘n’); my $res = $req->new_response(200); $res->content_type(‘text/plain’); $res->body($body); return $res->finalize; };
    71. 71. Plack::Test Unified interface to write tests with Mock HTTP and Live HTTP
    72. 72. use Plack::Test; use HTTP::Request::Common; my $app = sub { my $env = shift; return [ $status, $header, $body ]; }; test_psgi app => $app, client => sub { my $cb = shift; my $req = GET “http://localhost/foo”; my $res = $cb->($req); # test $res; };
    73. 73. use Plack::Test; use HTTP::Request::Common; $Plack::Test::Impl = “Server”; my $app = sub { my $env = shift; return [ $status, $header, $body ]; }; test_psgi app => $app, client => sub { my $cb = shift; my $req = GET “http://localhost/foo”; my $res = $cb->($req); # test $res; };
    74. 74. Streaming event loop / long-poll
    75. 75. # Pull streaming for blocking server use IO::Handle::Util qw(io_from_getline); my $app = sub { my $env = shift; my $io = io_from_getline sub { return $chunk; # undef when done }; return [ $status, $header, $io ]; };
    76. 76. # Push streaming for non-blocking server use AnyEvent; use JSON; my $app = sub { my $env = shift; return sub { my $respond = shift; my $w = $respond->([ 200, $headers ]); AnyEvent::Example->fetch(sub { $w->write(JSON::encode_json($_[0])); $w->close; }); }; };
    77. 77. Non-blocking servers AnyEvent, Coro, POE, Danga::Socket
    78. 78. Non-blocking framework Tatsumaki http://github.com/miyagawa/Tatsumaki
    79. 79. Other Servers
    80. 80. nginx embedded perl http://github.com/yappo/nginx-psgi-patchs
    81. 81. mod_psgi http://github.com/spiritloose/mod_psgi
    82. 82. evpsgi http://github.com/sekimura/evpsgi
    83. 83. Perlbal plugin http://github.com/miyagawa/Perlbal-Plugin-PSGI
    84. 84. Cloud
    85. 85. WSGI (PEP-333) mod_wsgi, Paste, AppEngine Django, CherryPy, Pylons
    86. 86. Rack Passenger, Thin, Unicorn, Heroku Rails, Merb, Sinatra
    87. 87. What if GAE Perl comes with PSGI ...
    88. 88. Summary • PSGI is an interface, Plack is the code. • We have many (pretty fast) servers. • We have adapters and tools for most web frameworks. • Use it!
    89. 89. http://github.com/miyagawa/Plack http://plackperl.org/ http://advent.plackperl.org/ ←NEW! irc://irc.perl.org/#plack
    90. 90. Questions?
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×