Plack
Superglue for Perl Web Frameworks
         Tatsuhiko Miyagawa
           Perl Oasis 2010
Tatsuhiko Miyagawa

• Japanese, lives in San Francisco
• Works at Six Apart
• 170+ CPAN modules (id:MIYAGAWA)
• @miyagawa
...
Background
40 slides of why we need Plack.
   May I fast-forward them?
      (since Stevan spoiled)
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?
Attempt:
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
 Moose is non-realistic in CGI environment
 Mouse is lovely but has its own problems :p
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 great stuff
from Python/Ruby
WSGI (Python)
   Rack
WSGI (PEP-333)
mod_wsgi, Paste, AppEngine
 Django, CherryPy, Pylons
Rack
Passenger, thin, Unicorn, Mongrel, Heroku
            Rails, Merb, Sinatra
WSGI/Rack
 Completely separate interface
from the actual implementation
Approach
Split HTTP::Engine
 into three parts
Interface
       Servers
Utils & Middleware
PSGI (interface)
HTTP::Server::PSGI etc. (servers)
     Plack (utils & middleware)
PSGI
Perl Web Server Gateway Interface
Interface
WARNING
You DON’T need to care about these
   interface details unless you are
framework or middleware developers
   (But ...
# WSGI
def hello(environ, start_response):
 start_response(“200 OK”, [
   (‘Content-Type’, ‘text/plain’)
 ])
 return [“Hel...
# Rack
class Hello
 def call(env)
   return [
     200,
     { “Content-Type” => ”text/plain” },
     [“Hello World”]
   ]...
# PSGI
my $app = sub {
   my $env = shift;
   return [
      200,
      [ ‘Content-Type’, ‘text/plain’ ],
      [ ‘Hello W...
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::Util
Easily turns perl code ref into a IO::Handle
Streaming interface
my $app = sub {
  my $env = shift;
  return sub {
    my $respond = shift;
    # You could do some event loop
    # to del...
my $app = sub {
  my $env = shift;
  return sub {
    my $respond = shift;
    my $w = $respond->([ $status, $header ]);
 ...
Streaming Interface
 Originally designed for non-blocking servers
Now available for most servers incl. CGI, Apache
Catalyst            CGI::App              Jifty        Tatsumaki


                                                    Pla...
PSGI adaptation
Maypole Mason Mojo Sledge Catalyst Spoon PageKit
 AxKit Egg Gantry Continuity Solstice Mojolicious
Tripletail Konstrukt Re...
Maypole Mason Mojo Sledge Catalyst Spoon PageKit
 AxKit Egg Gantry Continuity Solstice Mojolicious
Tripletail Konstrukt Re...
Applications
MT::App, WebGUI
Plack
“PSGI toolkit”
HTTP::Server::PSGI
 Reference PSGI web server
      bundled in Plack
Very fast
 3000 QPS on standalone
15000 QPS with prefork :)
Plack::Handler
Connects PSGI apps to Web servers
 CGI, FastCGI, Apache, Standalone
Utilities
Plackup
Run PSGI app instantly from CLI
     (inspired by rackup)
Plack::Runner
            plackup backend
Use this to make CLI for your web app
Middleware
my $app = sub {
   my $env = shift;
   return [ $status, $header, $body ];
};

my $mw = sub {
   my $env = shift;
   # do ...
Middleware
    Debug, Session, Runtime, Static, AccessLog,
  ConditionalGET, ErrorDocument, StackTrace,
Auth::Basic, Auth:...
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...
plackup compatible
plackup -e ‘enable “Foo”;’ app.psgi
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 middleware 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 ...
Test::WWW::Mechanize::PSGI
           acme++
Other PSGI Servers
Non-blocking servers
     psgi.nonblocking = true
AnyEvent, Coro, POE, Danga::Socket
Tatsumaki
 Non-blocking Web App framework
Comet, Server push, async HTTP client
http://github.com/miyagawa/Tatsumaki
Nomo
Unixy PSGI web servers with supervisors support
       http://github.com/miyagawa/Nomo
Re’em
Unicorn in Moose + FCGI::Manager
 http://github.com/perigrin/re-em
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
Catalyst            CGI::App              Jifty        Tatsumaki


                                                    Pla...
DEMO
Recent Updates
Common Confusions
“Is Plack a (new)
  framework?”
No.
Plack is intended to be used by developers for
   framework, web servers and middleware.
“But what is this
Plack::Request then?”
Ugh.
Plack::Request can be used as a micro framework.
   But our plan is to rename the existing one.
“Is Plack a web server?”
Not anymore.
Decided to give web servers ::PSGI name such as:
    HTTP::Server::PSGI, PoCo::Server::PSGI,
         AnyEven...
“Implements PSGI
  = use Plack?”
Yeah, but not
 necessarily.
Future
PSGI 1.1
psgi.streaming
  becomes SHOULD (from MAY)
Will be BufferedStreaming middleware
psgi.input
read callback (for WebSockets)
psgi.logger
Optional: Log::Dispatch-ish logger object
useful for Debug and FirePHP integration
psgix.session
Optional: Session as a hash ref
      (API is in Piglet)
Plack 1.0
HTTP::Server::PSGI
 (partial) HTTP/1.1 support
   pull prefork out of core
refactoring loaders
Restarter, Shotgun, gateway.cgi
   Plack::Handler renames
Merge Plack::Request
   Becomes a library for middleware writers
Make it work better when created multiple times
Summary

• PSGI is an interface, Plack is the code.
• We have many (pretty fast) PSGI servers.
• We have adapters and tool...
http://github.com/miyagawa/Plack
        http://plackperl.org/
   http://advent.plackperl.org/
      irc://irc.perl.org/#p...
BTW
We can fix this.
1) Help me SEO
 <a href=”http://plackperl.org/”>
(put “Perl” and “Web” here)</a>
2) More insanely:
% ls -l perlwebserver-0.3/lib/PerlWebServer/Module/
total 208
-rw-r--r-- 1 miyagawa staff 6029 Dec 15 2000 mod_cgi.pm
-rw-...
httpi: I gave up.
There is tools/phproxy which does similar things.
Questions?
Plack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and servers
Upcoming SlideShare
Loading in...5
×

Plack perl superglue for web frameworks and servers

9,382

Published on

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

No Downloads
Views
Total Views
9,382
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
0
Comments
0
Likes
13
Embeds 0
No embeds

No notes for slide
  • Plack perl superglue for web frameworks and servers

    1. 1. Plack Superglue for Perl Web Frameworks Tatsuhiko Miyagawa Perl Oasis 2010
    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. 40 slides of why we need Plack. May I fast-forward them? (since Stevan spoiled)
    5. 5. Web Frameworks
    6. 6. 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
    7. 7. Most of them run on mod_perl and CGI
    8. 8. Some run on FastCGI
    9. 9. Some run standalone
    10. 10. Very few supports non-blocking
    11. 11. Because:
    12. 12. No common server environment layers
    13. 13. CGI.pm
    14. 14. Runs “fine” on: CGI, FastCGI, mod_perl (1 & 2) Standalone (with HTTP::Server::Simple)
    15. 15. CGI.pm = LCD It’s also Perl core
    16. 16. :-(
    17. 17. Catalyst The most popular framework as of today
    18. 18. Catalyst::Engine::* Server abstractions. Well supported Apache, FCGI and Standalone No CGI.pm
    19. 19. CGI.pm Jifty, CGI::Application, Spoon mod_perl centric Mason, Sledge, PageKit, WebGUI Adapters Catalyst, Maypole, Squatting
    20. 20. Problems: Duplicated efforts No fair performance evaluations
    21. 21. Question: Can we share?
    22. 22. Attempt: HTTP::Engine
    23. 23. HTTP::Engine Lots of adapters (FCGI, Apache2, POE) Clean Request/Response API Written by Yappo, tokuhirom and others
    24. 24. Problems
    25. 25. Mo[ou]se everywhere Moose is non-realistic in CGI environment Mouse is lovely but has its own problems :p
    26. 26. Monolithic All implementations share HTTP::Engine roles and builders, which is sometimes hard to adapt and has less place for optimizations.
    27. 27. APIs everywhere Most frameworks have their request/response API Sometimes there are gaps. Annoying to write bridges and wrappers
    28. 28. Solution
    29. 29. Steal great stuff from Python/Ruby
    30. 30. WSGI (Python) Rack
    31. 31. WSGI (PEP-333) mod_wsgi, Paste, AppEngine Django, CherryPy, Pylons
    32. 32. Rack Passenger, thin, Unicorn, Mongrel, Heroku Rails, Merb, Sinatra
    33. 33. WSGI/Rack Completely separate interface from the actual implementation
    34. 34. Approach Split HTTP::Engine into three parts
    35. 35. Interface Servers Utils & Middleware
    36. 36. PSGI (interface) HTTP::Server::PSGI etc. (servers) Plack (utils & middleware)
    37. 37. PSGI Perl Web Server Gateway Interface
    38. 38. Interface
    39. 39. WARNING You DON’T need to care about these interface details unless you are framework or middleware developers (But i guess many of you are ...)
    40. 40. # WSGI def hello(environ, start_response): start_response(“200 OK”, [ (‘Content-Type’, ‘text/plain’) ]) return [“Hello World”]
    41. 41. # Rack class Hello def call(env) return [ 200, { “Content-Type” => ”text/plain” }, [“Hello World”] ] end end
    42. 42. # PSGI my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
    43. 43. PSGI application code reference $app = sub {...};
    44. 44. my $app = sub { my $env = shift; return [ $status, $header, $body ]; };
    45. 45. environment hash $env: CGI-like env variables + psgi.input, psgi.errors etc.
    46. 46. my $app = sub { my $env = shift; return [ $status, $header, $body ]; };
    47. 47. Response array ref with three elements status code, headers (array ref) and body (IO-like or array ref)
    48. 48. my $app = sub { my $env = shift; return [ $status, $header, $body ]; };
    49. 49. $body IO::Handle-like getline() and close()
    50. 50. IO::Handle::Util Easily turns perl code ref into a IO::Handle
    51. 51. Streaming interface
    52. 52. 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 ]); }; };
    53. 53. my $app = sub { my $env = shift; return sub { my $respond = shift; my $w = $respond->([ $status, $header ]); $w->write($body); $w->write($body); ... $w->close; }; };
    54. 54. Streaming Interface Originally designed for non-blocking servers Now available for most servers incl. CGI, Apache
    55. 55. Catalyst CGI::App Jifty Tatsumaki Plack::Middleware PSGI Plack::Handler::* (CGI, FCGI, Apache) Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal
    56. 56. PSGI adaptation
    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
    58. 58. 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
    59. 59. Applications MT::App, WebGUI
    60. 60. Plack “PSGI toolkit”
    61. 61. HTTP::Server::PSGI Reference PSGI web server bundled in Plack
    62. 62. Very fast 3000 QPS on standalone 15000 QPS with prefork :)
    63. 63. Plack::Handler Connects PSGI apps to Web servers CGI, FastCGI, Apache, Standalone
    64. 64. Utilities
    65. 65. Plackup Run PSGI app instantly from CLI (inspired by rackup)
    66. 66. Plack::Runner plackup backend Use this to make CLI for your web app
    67. 67. Middleware
    68. 68. 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; };
    69. 69. Middleware Debug, Session, Runtime, Static, AccessLog, ConditionalGET, ErrorDocument, StackTrace, Auth::Basic, Auth::Digest, ReverseProxy, Refresh etc.
    70. 70. Plack::Middleware reusable and extensible Middleware framework Plack::Builder DSL in .psgi
    71. 71. my $app = sub { return [ $status, $header, $body ]; }; use Plack::Builder; builder { enable “Static”, root => “/htdocs”, path => qr!^/static/!; enable “Deflater”; # gzip/deflate $app; }
    72. 72. plackup compatible plackup -e ‘enable “Foo”;’ app.psgi
    73. 73. Plack::App::URLMap Multiplex multiple apps Integrated with Builder DSL
    74. 74. 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; }; }
    75. 75. CGI::PSGI Easy migration from CGI.pm
    76. 76. CGI::Emulate::PSGI CGI::Compile Easiest migration from CGI scripts (like Registry)
    77. 77. Plack::Request like libapreq (Apache::Request) wrapper APIs for middleware developers
    78. 78. Plack::Test Unified interface to write tests with Mock HTTP and Live HTTP
    79. 79. 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; };
    80. 80. 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; };
    81. 81. Test::WWW::Mechanize::PSGI acme++
    82. 82. Other PSGI Servers
    83. 83. Non-blocking servers psgi.nonblocking = true AnyEvent, Coro, POE, Danga::Socket
    84. 84. Tatsumaki Non-blocking Web App framework Comet, Server push, async HTTP client http://github.com/miyagawa/Tatsumaki
    85. 85. Nomo Unixy PSGI web servers with supervisors support http://github.com/miyagawa/Nomo
    86. 86. Re’em Unicorn in Moose + FCGI::Manager http://github.com/perigrin/re-em
    87. 87. nginx embedded perl http://github.com/yappo/nginx-psgi-patchs
    88. 88. mod_psgi http://github.com/spiritloose/mod_psgi
    89. 89. evpsgi http://github.com/sekimura/evpsgi
    90. 90. Perlbal plugin http://github.com/miyagawa/Perlbal-Plugin-PSGI
    91. 91. Catalyst CGI::App Jifty Tatsumaki Plack::Middleware PSGI Plack::Handler::* (CGI, FCGI, Apache) Apache lighttpd HTTP::Server::PSGI mod_psgi Perlbal
    92. 92. DEMO
    93. 93. Recent Updates
    94. 94. Common Confusions
    95. 95. “Is Plack a (new) framework?”
    96. 96. No. Plack is intended to be used by developers for framework, web servers and middleware.
    97. 97. “But what is this Plack::Request then?”
    98. 98. Ugh. Plack::Request can be used as a micro framework. But our plan is to rename the existing one.
    99. 99. “Is Plack a web server?”
    100. 100. Not anymore. Decided to give web servers ::PSGI name such as: HTTP::Server::PSGI, PoCo::Server::PSGI, AnyEvent::HTTPD::PSGI, etc.
    101. 101. “Implements PSGI = use Plack?”
    102. 102. Yeah, but not necessarily.
    103. 103. Future
    104. 104. PSGI 1.1
    105. 105. psgi.streaming becomes SHOULD (from MAY) Will be BufferedStreaming middleware
    106. 106. psgi.input read callback (for WebSockets)
    107. 107. psgi.logger Optional: Log::Dispatch-ish logger object useful for Debug and FirePHP integration
    108. 108. psgix.session Optional: Session as a hash ref (API is in Piglet)
    109. 109. Plack 1.0
    110. 110. HTTP::Server::PSGI (partial) HTTP/1.1 support pull prefork out of core
    111. 111. refactoring loaders Restarter, Shotgun, gateway.cgi Plack::Handler renames
    112. 112. Merge Plack::Request Becomes a library for middleware writers Make it work better when created multiple times
    113. 113. 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!
    114. 114. http://github.com/miyagawa/Plack http://plackperl.org/ http://advent.plackperl.org/ irc://irc.perl.org/#plack
    115. 115. BTW
    116. 116. We can fix this.
    117. 117. 1) Help me SEO <a href=”http://plackperl.org/”> (put “Perl” and “Web” here)</a>
    118. 118. 2) More insanely:
    119. 119. % ls -l perlwebserver-0.3/lib/PerlWebServer/Module/ total 208 -rw-r--r-- 1 miyagawa staff 6029 Dec 15 2000 mod_cgi.pm -rw-r--r-- 1 miyagawa staff 71770 Dec 15 2000 mod_homer.pm -rw-r--r-- 1 miyagawa staff 5337 Jan 15 15:29 mod_psgi.pm -rw-r--r-- 1 miyagawa staff 7394 Dec 15 2000 mod_ssi.pm
    120. 120. httpi: I gave up. There is tools/phproxy which does similar things.
    121. 121. Questions?

    ×