O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.
PSGI and Plack
   Tatsuhiko Miyagawa
PSGI
Perl Web Server Gateway Interface
Plack
PSGI ref. implementations
          Utilities
A Perl port of:
Python’s WSGI and Ruby’s Rack
  (will talk about them later)
WHY
Web Frameworks
Maypole Mason Mojo Sledge Catalyst Spoon PageKit
  AxKit Egg Gantry Continuity Solstice Mojolicious
    Tripletail Konstru...
Most of them run on
 mod_perl and CGI
Some run on FCGI
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
> grep ‘(CGI.pm|ENV)’ lib/MT/App.pm
         if ( my $path_info = $ENV{PATH_INFO} ) {
                # defined which inter...
Not cool.
Catalyst
The most popular framework as of today
Catalyst::Engine::*
            Server abstractions.
Well supported Apache, FCGI and Standalone
Problems:
       Duplicated efforts
No fair performance evaluations
Catalyst::Engine
for the rest of us
= HTTP::Engine
HTTP::Engine
Lots of adapters (FCGI, Apache2, POE)
     Clean Request/Response API
Written by Yappo, tokuhirom and others
Problem
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, Tornado, Paste, GAE
  Django, CherryPy, Pylons
Rack
Passenger, Thin, rack, Heroku
     Rails, Merb, Sinatra
Split HTTP::Engine
 into three parts
Interface
Implementations
    Utilities
PSGI (interface)
Plack::Server (implementations)
      Plack::* (utilities)
PSGI
Interface
my $app = sub {
   my $env = shift;
   # ...
   return [ $status, $header, $body ];
};
PSGI application
   code reference
   $app = sub {...};
environment hash
$env: CGI-like env variables
+ psgi.input, psgi.errors etc.
Why a big hash?
Easy to adapt if you have CGI adapter
  Also follows what WSGI/Rack do
Response
 array ref with three elements
status code, headers (array ref)
and body (IO-like or array ref)
$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...
Frameworks
Write an adapter to return
PSGI application code ref.
Servers
   Set up $env, run the app
and emits response out of $res
Middleware
   Plays both side
“Application wrapper”
Plack
Plack::Server
 reference server implementations
  Standalone, FCGI, Apache2, CGI
Standalone, Prefork, AnyEvent, Coro
Very fast
 5000 QPS on standalone
15000 QPS with prefork :)
Framework Adapters
  CGI::Application, Catalyst, Maypole
Mason, Squatting, Mojo, HTTP::Engine etc.
Applications
MT::App, WebGUI
Utilities
Plackup
Run PSGI app instantly from CLI
     (inspired by rackup)
DEMO
Middlewares
my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

my $mw = sub {
   my $env = shift;
   # do ...
Middlewares
Static, AccessLog, ConditionalGET
 ErrorDocument, StackTrace etc.
Plack::Middleware
  reusable and extensible
  Middleware framework
 Plack::Builder DSL in .psgi
CGI::PSGI
Easy migration from CGI.pm
Plack::Request
    like libapreq (Apache::Request)
wrapper APIs for framework developers
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
use IO::Handle::Util qw(io_from_getline);

my $app = sub {
   my $env = shift;
   my $io = io_from_getline sub {
      ret...
use IO::Writer; # TBD: API might change
use AnyEvent::Timer;

my $app = sub {
   my $env = shift;
   my $io = writer {
   ...
Other Servers
nginx embedded perl
 http://github.com/yappo/nginx-psgi-patchs
mod_psgi
http://github.com/spiritloose/mod_psgi
Gearman Dispatcher?
Cloud
WSGI (PEP-333)
mod_wsgi, Tornado, Paste, GAE
  Django, CherryPy, Pylons
Rack
Passenger, Thin, rack, 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/
Questions?
Próximos SlideShares
Carregando em…5
×

Intro to PSGI and Plack

Introduction to PSGI and Plack.

  • Seja o primeiro a comentar

Intro to PSGI and Plack

  1. 1. PSGI and Plack Tatsuhiko Miyagawa
  2. 2. PSGI Perl Web Server Gateway Interface
  3. 3. Plack PSGI ref. implementations Utilities
  4. 4. A Perl port of: Python’s WSGI and Ruby’s Rack (will talk about them later)
  5. 5. WHY
  6. 6. Web Frameworks
  7. 7. Maypole Mason Mojo Sledge Catalyst Spoon PageKit AxKit Egg Gantry Continuity Solstice Mojolicious Tripletail Konstrukt Reflection Jifty Cyclone3 OpenInteract Squatting Dancer CGI::Application Nanoa Ark Angelos Noe Schenker
  8. 8. Most of them run on mod_perl and CGI
  9. 9. Some run on FCGI
  10. 10. Some run standalone
  11. 11. Very few supports non-blocking
  12. 12. Because:
  13. 13. No common server environment layers
  14. 14. CGI.pm
  15. 15. Runs fine on: CGI, FastCGI, mod_perl (1 & 2) Standalone (with HTTP::Server::Simple)
  16. 16. CGI.pm = LCD It’s also Perl core
  17. 17. > grep ‘(CGI.pm|ENV)’ lib/MT/App.pm if ( my $path_info = $ENV{PATH_INFO} ) { # defined which interferes with CGI.pm determining the delete $ENV{PATH_INFO}; # CGI.pm has this terrible flaw in that if a POST is in effect, my $query_string = $ENV{'QUERY_STRING'} if defined $ENV{'QUERY_STRING'}; $query_string ||= $ENV{'REDIRECT_QUERY_STRING'} if defined $ENV{'REDIRECT_QUERY_STRING'}; my $len = $ENV{CONTENT_LENGTH} || 0; return $ENV{ 'HTTP_' . $key }; $app->{request_method} = $ENV{REQUEST_METHOD} || ''; ## Older versions of CGI.pm didn't have an 'upload' method. if ( my $host = $ENV{HTTP_HOST} ) { : $ENV{REMOTE_ADDR}); $cwd = $ENV{DOCUMENT_ROOT} || $app->mt_dir;
  18. 18. Not cool.
  19. 19. Catalyst The most popular framework as of today
  20. 20. Catalyst::Engine::* Server abstractions. Well supported Apache, FCGI and Standalone
  21. 21. Problems: Duplicated efforts No fair performance evaluations
  22. 22. Catalyst::Engine for the rest of us
  23. 23. = HTTP::Engine
  24. 24. HTTP::Engine Lots of adapters (FCGI, Apache2, POE) Clean Request/Response API Written by Yappo, tokuhirom and others
  25. 25. Problem
  26. 26. Mo[ou]se everywhere Mouse is light but still overspec for some env.
  27. 27. Monolithic All implementations share HTTP::Engine roles and builders, which is sometimes hard to adapt and has less place for optimizations.
  28. 28. APIs everywhere Most frameworks have their request/response API Sometimes there are gaps. Annoying to write bridges and wrappers
  29. 29. Solution
  30. 30. Steal good stuff from Python/Ruby
  31. 31. WSGI (Python) Rack
  32. 32. WSGI (PEP-333) mod_wsgi, Tornado, Paste, GAE Django, CherryPy, Pylons
  33. 33. Rack Passenger, Thin, rack, Heroku Rails, Merb, Sinatra
  34. 34. Split HTTP::Engine into three parts
  35. 35. Interface Implementations Utilities
  36. 36. PSGI (interface) Plack::Server (implementations) Plack::* (utilities)
  37. 37. PSGI
  38. 38. Interface
  39. 39. my $app = sub { my $env = shift; # ... return [ $status, $header, $body ]; };
  40. 40. PSGI application code reference $app = sub {...};
  41. 41. environment hash $env: CGI-like env variables + psgi.input, psgi.errors etc.
  42. 42. Why a big hash? Easy to adapt if you have CGI adapter Also follows what WSGI/Rack do
  43. 43. Response array ref with three elements status code, headers (array ref) and body (IO-like or array ref)
  44. 44. $body IO::Handle-like getline() and close()
  45. 45. IO::Handle-like We really envy Python/Ruby for built-in iterators (Perl’s filehandle is also an object, but it really sucks)
  46. 46. Frameworks Write an adapter to return PSGI application code ref.
  47. 47. Servers Set up $env, run the app and emits response out of $res
  48. 48. Middleware Plays both side “Application wrapper”
  49. 49. Plack
  50. 50. Plack::Server reference server implementations Standalone, FCGI, Apache2, CGI Standalone, Prefork, AnyEvent, Coro
  51. 51. Very fast 5000 QPS on standalone 15000 QPS with prefork :)
  52. 52. Framework Adapters CGI::Application, Catalyst, Maypole Mason, Squatting, Mojo, HTTP::Engine etc.
  53. 53. Applications MT::App, WebGUI
  54. 54. Utilities
  55. 55. Plackup Run PSGI app instantly from CLI (inspired by rackup)
  56. 56. DEMO
  57. 57. Middlewares
  58. 58. 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; };
  59. 59. Middlewares Static, AccessLog, ConditionalGET ErrorDocument, StackTrace etc.
  60. 60. Plack::Middleware reusable and extensible Middleware framework Plack::Builder DSL in .psgi
  61. 61. CGI::PSGI Easy migration from CGI.pm
  62. 62. Plack::Request like libapreq (Apache::Request) wrapper APIs for framework developers
  63. 63. Plack::Test Unified interface to write tests with Mock HTTP and Live HTTP
  64. 64. 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; };
  65. 65. 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; };
  66. 66. Streaming event loop / long-poll
  67. 67. 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 ]; };
  68. 68. use IO::Writer; # TBD: API might change use AnyEvent::Timer; my $app = sub { my $env = shift; my $io = writer { my $h = shift; my $t; $t = AE::timer 0, 1, sub { $t; $h->push_write($stuff); }; }; return [ $status, $header, $io ]; };
  69. 69. Other Servers
  70. 70. nginx embedded perl http://github.com/yappo/nginx-psgi-patchs
  71. 71. mod_psgi http://github.com/spiritloose/mod_psgi
  72. 72. Gearman Dispatcher?
  73. 73. Cloud
  74. 74. WSGI (PEP-333) mod_wsgi, Tornado, Paste, GAE Django, CherryPy, Pylons
  75. 75. Rack Passenger, Thin, rack, Heroku Rails, Merb, Sinatra
  76. 76. What if GAE Perl comes with PSGI ...
  77. 77. 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!
  78. 78. http://github.com/miyagawa/Plack http://plackperl.org/
  79. 79. Questions?

×