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.

Plack at YAPC::NA 2010

7,858 views

Published on

Published in: Technology
  • Be the first to comment

Plack at YAPC::NA 2010

  1. 1. Plack Superglue for Perl Web Frameworks Tatsuhiko Miyagawa YAPC::NA 2010
  2. 2. Tatsuhiko Miyagawa • Lives in San Francisco • Software Engineer @ Six Apart • http://search.cpan.org/~miyagawa/ • @miyagawa • http://bulknews.typepad.com/
  3. 3. Web Applications
  4. 4. Hello World
  5. 5. #!/usr/bin/perl use strict; print “Content-Type: text/plainrnrn”; print “Hello World”;
  6. 6. use FCGI; my $req = FCGI::Request(); while ($req->Accept >= 0) { print “Content-Type: text/plainrnrn”; print “Hello World”; }
  7. 7. package HelloWorld; use strict; use Apache::RequestRec; use Apache::RequestIO; use Apache::Const -compile => qw(OK); sub handler { my $r = shift; $r->content_type(‘text/plain’); $r->print(“Hello World”); return Apache::Const::OK; } 1;
  8. 8. package HelloWorld; use base qw(HTTP::Server::Simple::CGI); sub handle_request { my($self, $cgi) = @_; print “HTTP/1.0 200 OKrn”; print “Content-Type: text/plainrnrn”; print “Hello World”; } 1;
  9. 9. All similar but slightly different
  10. 10. There is (was) one common way to do all of this.
  11. 11. #!/usr/bin/perl use CGI; my $q = CGI->new; print $q->header(‘text/plain’); print “Hello World”;
  12. 12. Happens to work on: CGI, FastCGI, mod_perl (HTTP::Server::Simple::CGI)
  13. 13. CGI.pm? meh
  14. 14. Frameworks to the rescue!
  15. 15. 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
  16. 16. MANY web frameworks
  17. 17. CGI.pm Jifty, CGI::Application, Spoon mod_perl centric Mason, Sledge, PageKit, WebGUI Adapters Catalyst, Maypole, Squatting
  18. 18. That was 2008.
  19. 19. Steal great idea from Python/Ruby
  20. 20. WSGI (Python) Rack (Ruby)
  21. 21. WSGI (PEP-333)
  22. 22. # WSGI def hello(environ, start_response): start_response(“200 OK”, [ (‘Content-Type’, ‘text/plain’) ]) return [“Hello World”]
  23. 23. WSGI • Django • mod_wsgi • Bottle • Paste • CherryPy • gunicorn • Tornado • uWSGI • Pylons • wsgiref • Flask • Google AppEngine
  24. 24. Django Bottle Flask Tornado WSGI middleware WSGI wsgi handlers Apache lighttpd nginx mod_wsgi GAE
  25. 25. Rack
  26. 26. # Rack class Hello def call(env) return [ 200, { “Content-Type” => ”text/plain” }, [“Hello World”] ] end end
  27. 27. Rack • Rails • Unicorn • Merb • Thin • Sinatra • Mongrel • Camping • Rainbows! • Ramaze • Phusion Passenger • etc. • Heroku
  28. 28. Rails Merb Sinatra Ramaze Rack middleware Rack Rack handlers Apache lighttpd Thin Unicorn Mongrel
  29. 29. PSGI Perl Web Server Gateway Interface
  30. 30. Interface
  31. 31. # WSGI def hello(environ, start_response): start_response(“200 OK”, [ (‘Content-Type’, ‘text/plain’) ]) return [“Hello World”]
  32. 32. # Rack class Hello def call(env) return [ 200, { “Content-Type” => ”text/plain” }, [“Hello World”] ] end end
  33. 33. # PSGI my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  34. 34. PSGI application code reference $app = sub {...};
  35. 35. my $app = sub { my $env = shift; return [ $status, $header, $body ]; };
  36. 36. environment hash $env: CGI-like env variables + psgi.input, psgi.errors etc.
  37. 37. my $app = sub { my $env = shift; return [ $status, $header, $body ]; };
  38. 38. Response array ref with three elements status code, headers (array ref) and body (IO-like or array ref)
  39. 39. my $app = sub { my $env = shift; return [ $status, $header, $body ]; };
  40. 40. $body IO::Handle-like getline() and close()
  41. 41. That’s it.
  42. 42. # PSGI my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  43. 43. Now you’ve got a PSGI application.
  44. 44. PSGI makes it so simple to:
  45. 45. Write a new Perl web app & framework
  46. 46. Write a new Perl web server
  47. 47. Catalyst CGI::App Jifty Tatsumaki Plack::Middleware PSGI Plack::Handler::* (CGI, FCGI, Apache) Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal
  48. 48. PSGI adaptation
  49. 49. 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
  50. 50. 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
  51. 51. Applications Movable Type 6, WebGUI 8
  52. 52. # Catalyst use MyApp; MyApp->setup_engine(‘PSGI’); my $app = sub { MyApp->run(@_) }; # $app is a PSGI app!
  53. 53. # Jifty use MyPonyApp; my $app = MyPonyApp->psgi_app; # $app is a PSGI app!
  54. 54. # Dancer use Dancer; get ‘/’ => sub { “Hello World”; }; dance; # returns a PSGI app!
  55. 55. # Mojolicious::Lite use Mojolicious::Lite; get ‘/:name’ => sub { my $self = shift; $self->render_text(‘Hello!’); }; shagadelic; # returns PSGI app
  56. 56. # Web::Simple use Web::Simple ‘MyApp’; package MyApp; dispatch { sub(GET) { [ 200, [...], [ ‘Hello’ ] ]; } }; my $app = MyApp->as_psgi; # $app is a PSGI app!
  57. 57. Plack “PSGI toolkit”
  58. 58. HTTP::Server::PSGI Reference PSGI web server bundled in Plack
  59. 59. Plackup Runs PSGI app instantly from CLI (inspired by rackup)
  60. 60. > plackup app.psgi
  61. 61. Plack::Handler Connects PSGI apps to Web servers CGI, FastCGI, Apache, SCGI
  62. 62. PSGI Web Servers
  63. 63. Starman UNIX Preforking HTTP servers (like Unicorn.rb) HTTP/1.1 chunk + keep-alives / Very Fast
  64. 64. Starlet Simpler UNIX HTTP/1.0 Server Best used with Server::Starter and nginx/lighttpd
  65. 65. Twiggy Non-blocking web server (like Thin.rb) based on AnyEvent framework
  66. 66. Corona Coroutine for each connection based on Coro.pm
  67. 67. HTTP::Server::Simple::PSGI Zero-deps other than HTTP::Server::Simple Best for embedding PSGI applications
  68. 68. uWSGI http://projects.unbit.it/uwsgi/
  69. 69. Perlbal plugin http://github.com/miyagawa/Perlbal-Plugin-PSGI
  70. 70. nginx embedded perl http://github.com/yappo/nginx-psgi-patchs
  71. 71. mod_psgi http://github.com/spiritloose/mod_psgi
  72. 72. evpsgi http://github.com/sekimura/evpsgi
  73. 73. Feersum http://github.com/stash/Feersum
  74. 74. 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
  75. 75. Middleware
  76. 76. PSGI Middleware Wraps a PSGI application to add pre/post processing
  77. 77. 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; };
  78. 78. PSGI Middleware coderef -> coderef Higher-order functions
  79. 79. Middleware Debug, Session, Logger, Runtime, Static, Lint, AccessLog, ConditionalGET, ErrorDocument, StackTrace, Auth::Basic, Auth::Digest, ReverseProxy, Refresh, Auth::OAuth, Hippie, Throttle
  80. 80. Plack::Middleware reusable and extensible Middleware framework Plack::Builder DSL in .psgi
  81. 81. my $app = sub { return [ $status, $header, $body ]; }; use Plack::Builder; builder { enable “Static”, root => “/htdocs”, path => qr!^/static/!; enable “Deflater”; # gzip/deflate $app; }
  82. 82. plackup compatible plackup -e ‘enable “Foo”;’ app.psgi
  83. 83. Middleware Write once, run in every framework
  84. 84. DEMO
  85. 85. Plack::App::URLMap Multiplex multiple apps Integrated with Builder DSL
  86. 86. 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; }; }
  87. 87. CGI::PSGI Easy migration from CGI.pm
  88. 88. CGI::Emulate::PSGI CGI::Compile Easiest migration from CGI scripts (like Registry)
  89. 89. Plack::Request like libapreq (Apache::Request) wrapper APIs for middleware developers
  90. 90. Plack::Test Unified interface to write tests with Mock HTTP and Live HTTP
  91. 91. 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; };
  92. 92. 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; };
  93. 93. Plack::App::* ready-to-use applications
  94. 94. Plack::App::Directory Static content file server
  95. 95. Plack::App::Proxy (non-blocking) proxy server Can be used as reverse proxy as well
  96. 96. Plack::App::CGIBin mount /cgi-bin as PSGI applications
  97. 97. Plack::App::FCGIDispatcher Connect to FCGI daemon (even in Ruby, Python, C)
  98. 98. Plack::App::JSP Runs JavaScript PSGI apps :)
  99. 99. Real World Plack/PSGI
  100. 100. You should join!
  101. 101. > cpanm Plack > cpanm Task::Plack
  102. 102. Haven’t used cpanm? Come to Nationwide (Cartoon 2) Wednesday 9:30
  103. 103. Cloud? (Heroku, GAE)
  104. 104. Sunaba http://sunaba.plackperl.org/
  105. 105. Runs on dankogai’s Sandbox
  106. 106. You can even try: system(“rm -fr /”); while (1) { }
  107. 107. Summary • 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!
  108. 108. Remember: Plack is < 1y old
  109. 109. Lots of (exciting) things going on.
  110. 110. http://blog.plackperl.org/
  111. 111. http://github.com/miyagawa/Plack http://plackperl.org/ irc://irc.perl.org/#plack
  112. 112. Questions?

×