Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

PSGI/Plack OSDC.TW

6,713 views

Published on

Published in: Technology
  • Be the first to comment

PSGI/Plack OSDC.TW

  1. 1. Plack Superglue for Perl Web Frameworks Tatsuhiko Miyagawa OSDC. 2010
  2. 2. • • Six Apart • 177 CPAN modules (id:MIYAGAWA) • @miyagawa • http://bulknews.typepad.com/
  3. 3. Web Frameworks (in Perl)
  4. 4. Sharing, Stealing and Importing
  5. 5. Web Frameworks in Perl
  6. 6. Many ways to write Perl web applications
  7. 7. 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 Amon Apache2::WebApp Web::Simple Apache2::REST SweetPea Hydrant Titanium
  8. 8. Some ways to run Perl web applications
  9. 9. CGI, FastCGI & mod_perl
  10. 10. CGI.pm
  11. 11. Runs “fine” on: CGI, FastCGI, mod_perl (1 & 2) Standalone (with HTTP::Server::Simple)
  12. 12. CGI.pm = LCD Perl core module
  13. 13. 8803 lines of code First ver. in Nov.1995
  14. 14. :-(
  15. 15. CGI.PM MUST DIE!
  16. 16. (just kidding)
  17. 17. Catalyst The most popular perl web framework as of today
  18. 18. Catalyst::Engine::* Server abstractions. Apache, FastCGI, Standalone and Prefork No CGI.pm
  19. 19. CGI.pm Jifty, CGI::Application, Spoon mod_perl centric Mason, Sledge, PageKit, WebGUI Adapters Catalyst, Maypole, Squatting
  20. 20. Can we share?
  21. 21. ?
  22. 22. HTTP::Engine Yappo, tokuhirom and nothingmuch etc.
  23. 23. :-) Ported Catalyst engine code and made it sharable
  24. 24. :-( Monolithic code base No separation of interface & impl.
  25. 25. 2009
  26. 26. Steal great idea from Python/Ruby
  27. 27. Import stuff proven popular from Python/Ruby
  28. 28. PROVEN POPULAR!
  29. 29. Popular and successful in Python and Ruby
  30. 30. WSGI (Python) Rack (Ruby)
  31. 31. WSGI (PEP-333)
  32. 32. WSGI • Django • mod_wsgi • Bottle • Paste • CherryPy • gunicorn • Tornado • uWSGI • Pylons • wsgiref • Flask • Google AppEngine
  33. 33. Django Bottle Flask Tornado WSGI middleware WSGI wsgi handlers Apache lighttpd nginx mod_wsgi GAE
  34. 34. Rack
  35. 35. Rack • Rails • Unicorn • Merb • Thin • Sinatra • Mongrel • Camping • Rainbows! • Ramaze • Phusion Passenger • etc. • Heroku
  36. 36. Rails Merb Sinatra Ramaze Rack middleware Rack Rack handlers Apache lighttpd Thin Unicorn Mongrel
  37. 37. PSGI Perl Web Server Gateway Interface
  38. 38. Interface
  39. 39. # WSGI def hello(environ, start_response): start_response(“200 OK”, [ (‘Content-Type’, ‘text/plain’) ]) return [“Hello World”]
  40. 40. # Rack class Hello def call(env) return [ 200, { “Content-Type” => ”text/plain” }, [“Hello World”] ] end end
  41. 41. # PSGI my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  42. 42. PSGI application code reference $app = sub {...};
  43. 43. my $app = sub { my $env = shift; return [ $status, $header, $body ]; };
  44. 44. environment hash $env: CGI-like env variables + psgi.input, psgi.errors etc.
  45. 45. my $app = sub { my $env = shift; return [ $status, $header, $body ]; };
  46. 46. Response array ref with three elements status code, headers (array ref) and body (IO-like or array ref)
  47. 47. my $app = sub { my $env = shift; return [ $status, $header, $body ]; };
  48. 48. $body IO::Handle-like getline() and close()
  49. 49. IO::Handle::Util Easily turns perl code ref into a IO::Handle
  50. 50. Streaming interface
  51. 51. my $app = sub { my $env = shift; return sub { my $respond = shift; # You could do some event loop # to delay response (e.g. Comet) $respond->([ $status, $header, $body ]); }; };
  52. 52. my $app = sub { my $env = shift; return sub { my $respond = shift; my $w = $respond->([ $status, $header ]); $w->write($body); $w->write($body); ... $w->close; }; };
  53. 53. Streaming Interface Originally designed for non-blocking servers Now available for most servers incl. CGI, Apache
  54. 54. Catalyst CGI::App Jifty Tatsumaki Plack::Middleware PSGI Plack::Handler::* (CGI, FCGI, Apache) Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal
  55. 55. PSGI adaptation
  56. 56. 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 Amon Apache2::WebApp Web::Simple Apache2::REST SweetPea Hydrant Titanium
  57. 57. 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 Amon Apache2::WebApp Web::Simple Apache2::REST SweetPea Hydrant Titanium
  58. 58. Applications Movable Type, WebGUI
  59. 59. # Catalyst use MyApp; MyApp->setup_engine(‘PSGI’); my $app = sub { MyApp->run(@_) }; # $app is a PSGI app!
  60. 60. # Jifty use MyPonyApp; my $app = MyPonyApp->psgi_app; # $app is a PSGI app!
  61. 61. # Dancer use Dancer; get ‘/’ => sub { “Hello World”; }; use Dancer::Config ‘setting’; setting apphandler => ‘PSGI’; my $app = sub { my $r = Dancer::Request->new(shift); Dancer->dance($r); }; # $app is a PSGI app!
  62. 62. # Mojolicious::Lite use Mojolicious::Lite; get ‘/:name’ => sub { my $self = shift; $self->render_text(‘Hello!’); }; shagadelic; # returns PSGI app
  63. 63. # Web::Simple use Web::Simple ‘MyApp’; package MyApp; dispatch { sub(GET) { [ 200, [...], [ ‘Hello’ ] ]; } }; my $app = MyApp->as_psgi; # $app is a PSGI app!
  64. 64. Plack “PSGI toolkit”
  65. 65. HTTP::Server::PSGI Reference PSGI web server bundled in Plack
  66. 66. Plack::Handler Connects PSGI apps to Web servers CGI, FastCGI, Apache, SCGI
  67. 67. Plackup Runs PSGI app instantly from CLI (inspired by rackup)
  68. 68. > plackup app.psgi
  69. 69. DEMO
  70. 70. Middleware
  71. 71. 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; };
  72. 72. Middleware Debug, Session, Logger, Runtime, Static, AccessLog, ConditionalGET, ErrorDocument, StackTrace, Auth::Basic, Auth::Digest, ReverseProxy, Refresh etc. (Imported from Rack and Paste)
  73. 73. Plack::Middleware reusable and extensible Middleware framework Plack::Builder DSL in .psgi
  74. 74. my $app = sub { return [ $status, $header, $body ]; }; use Plack::Builder; builder { enable “Static”, root => “/htdocs”, path => qr!^/static/!; enable “Deflater”; # gzip/deflate $app; }
  75. 75. plackup compatible plackup -e ‘enable “Foo”;’ app.psgi
  76. 76. DEMO
  77. 77. Plack::App::URLMap Multiplex multiple apps Integrated with Builder DSL (Imported from Rack)
  78. 78. 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; }; }
  79. 79. CGI::PSGI Easy migration from CGI.pm
  80. 80. CGI::Emulate::PSGI CGI::Compile Easiest migration from CGI scripts (like Registry)
  81. 81. Plack::Request like libapreq (Apache::Request) wrapper APIs for middleware developers
  82. 82. Plack::Test Unified interface to write tests with Mock HTTP and Live HTTP
  83. 83. 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; };
  84. 84. 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; };
  85. 85. PSGI Web Servers
  86. 86. Starman UNIX Preforking HTTP servers (like Unicorn.rb) HTTP/1.1 chunk + keep-alives / Very Fast
  87. 87. Twiggy Non-blocking web server (like Thin.rb) based on AnyEvent framework
  88. 88. Corona Coroutine for each connection based on Coro.pm
  89. 89. HTTP::Server::Simple::PSGI Zero-deps other than HTTP::Server::Simple Best for embedding PSGI applications
  90. 90. nginx embedded perl http://github.com/yappo/nginx-psgi-patchs
  91. 91. mod_psgi http://github.com/spiritloose/mod_psgi
  92. 92. evpsgi http://github.com/sekimura/evpsgi
  93. 93. Perlbal plugin http://github.com/miyagawa/Perlbal-Plugin-PSGI
  94. 94. uWSGI http://projects.unbit.it/uwsgi/
  95. 95. Catalyst CGI::App Jifty Tatsumaki Plack::Middleware PSGI Plack::Handler::* (CGI, FCGI, Apache) Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal Starman Twiggy uWSGI Corona evpsgi
  96. 96. Play with it
  97. 97. > cpanm Plack > cpanm Task::Plack
  98. 98. Cloud? (Heroku, GAE)
  99. 99. Sunaba http://sunaba.plackperl.org/
  100. 100. Runs on ’s Sandbox ( )
  101. 101. You can even try: system(“rm -fr /”); while (1) { }
  102. 102. • PSGI is an interface, Plack is the code. • We have many (pretty fast) PSGI servers. • We have adapters and tools for most web frameworks. • Use it!
  103. 103. • Sharing is important. • Stealing is a good start. • Importing something successful is great.
  104. 104. http://github.com/miyagawa/Plack http://plackperl.org/ http://blog.plackperl.org/ irc://irc.perl.org/#plack
  105. 105. ?
  106. 106. :-)

×