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.

Tatsumaki

20,479 views

Published on

Published in: Technology

Tatsumaki

  1. 1. Tatsumaki non-blocking web framework built on Plack/AnyEvent Tatsuhiko Miyagawa Nov. 30th, 2009 / Shibuya.pm Tech Talks #12
  2. 2. PSGI
  3. 3. Perl Web Server Gateway Interface
  4. 4. Python’s WSGI Ruby’s Rack
  5. 5. my $app = sub { my $env = shift; return [ $status, $headers, $body ]; };
  6. 6. Plain Old Perl
  7. 7. Servers CGI, FastCGI, mod_perl1&2 Standalone, Prefork, AnyEvent, Coro, POE, Danga::Socket, nginx, mod_psgi, evhttpd, Perlbal
  8. 8. Frameworks Catalyst, Mason, Maypole, CGI::Application, Jifty Dancer, HTTP::Engine, Sqauatting, Continuity WebGUI, Movable Type, Ark, Angelos, Noe
  9. 9. Middleware Static, ConditionalGET, AccessLog, Chunked, Deflater, NYTProf, FCGIDispatcher, JSONP, StackTrace, Auth::Basic, XSendfile, Rewrite, JSConcat ...
  10. 10. Servers CGI, FastCGI, mod_perl1&2 Standalone, Prefork, AnyEvent, Coro, POE, Danga::Socket, nginx, mod_psgi, evhttpd, Perlbal
  11. 11. Non-blocking?
  12. 12. psgi.streaming
  13. 13. # delayed response my $app = sub { my $env = shift; return sub { my $respond = shift; $respond->([ $status, $headers, $body ]); };
  14. 14. # streaming content my $app = sub { my $env = shift; return sub { my $respond = shift; my $w = $respond->([ $status, $headers ]); some_event_loop(sub { $w->write($content); $w->close; }); };
  15. 15. WARNING psgi.streaming is an interface Servers may not work if event loop is not shared (Recommended to use AnyEvent in your app)
  16. 16. Frameworks?
  17. 17. Most frameworks do not support non-blocking interface. (Mojo 0.99 has IOLoop and Client)
  18. 18. Let’s make one!
  19. 19. Tatsumaki http://www.flickr.com/photos/88699006@N00/679056142/
  20. 20. Port of Tornado
  21. 21. Plack and AnyEvent All the way from the bottom to the top Handle thousands of connections with EV/epoll
  22. 22. Works with AnyEvent, POE, Coro, Danga::Socket and perlbal Because it’s AnyEvent!
  23. 23. You can use Any of AnyEvent::* libraries to do asynchronous tasks (unlike Mojo)
  24. 24. The first and only framework that uses psgi.streaming
  25. 25. package MainHandler; use base qw(Tatsumaki::Handler); sub get { my $self = shift; $self->write(“Hello World”); } package main; use Tatsumaki::Application; my $app = Tatsumaki::Application->new([ ‘/’ => ‘MainHandler’, ]);
  26. 26. Tatsumaki::HTTPClient AnyEvent::HTTP wrapper non-blocking HTTP client for Tatsumaki
  27. 27. package HTTPClientHandler; use base qw(Tatsumaki::Handler); __PACKAGE__->asynchronous(1); use Tatsumaki::HTTPClient; sub get { my $self = shift; my $client = Tatsumaki::HTTPClient->new; $client->get($api_url, sub { my $res = shift; my $body = $res->content; $self->write(...); $self->finish; }); }
  28. 28. Long-poll (comet)
  29. 29. package AsyncHandler; use base qw(Tatsumaki::Handler); __PACKAGE__->asynchronous(1); sub get { my $self = shift; my $t; $t = AE::timer 3, 0, sub { undef $t; $self->write(“Hello World”); $self->finish; }); } package main; use Tatsumaki::Application; my $app = Tatsumaki::Application->new([ ‘/’ => ‘AsyncHandler’, ]);
  30. 30. Tatsumaki::MessageQueue Pure perl MQ (in AnyEvent)
  31. 31. package LongPollHandler; use base qw(Tatsumaki::Handler); __PACKAGE__->asynchronous(1); use Tatsumaki::MessageQueue; sub get { my $self = shift; my $mq = Tatsumaki::MessageQueue- >instance(‘ch-name’); $mq->poll_once($client_id, sub { my @events = @_; $self->write(@events); $self->finish; }); }
  32. 32. package EventPostHandler; use base qw(Tatsumaki::Handler); sub post { my $self = shift; my $mq = Tatsumaki::MessageQueue- >instance(‘ch-name’); $mq->publish({ name => “NewComment”, ... }); $self->write({ success => 1 }); }
  33. 33. Multipart XHR JavaScript hack to emulate server push
  34. 34. package MXHRPollHandler; use base qw(Tatsumaki::Handler); __PACKAGE__->asynchronous(1); use Tatsumaki::MessageQueue; sub get { my $self = shift; $self->multipart_xhr_push(1); my $mq = Tatsumaki::MessageQueue- >instance(‘ch-name’); $mq->poll($client_id, sub { my @events = @_; $self->stream_write(@events); }); }
  35. 35. JS Client libraries jquery.ev DUI.Stream raphaeljs
  36. 36. DEMO
  37. 37. http://192.168.100.50:5000/chat/demo
  38. 38. Other apps github.com/gugod/Social github.com/miyagawa/Subfeedr github.com/audreyt/socialcalc github.com/clkao/Finance-GeniusTrader-Chart github.com/lestrrat/Hamaki github.com/yusukebe/Nagare
  39. 39. WHY
  40. 40. Web server resource
  41. 41. I/O bound !CPU bound
  42. 42. I/O bound web apps HTTP API proxy (e.g. OpenSocial) Mash up (XML, REST API) Real-time Web (Comet)
  43. 43. CPU bound jobs Database Servers Job Workers (TheSchwartz etc.)
  44. 44. Tatsumaki for I/O bound web
  45. 45. ✓ Non-blocking HTTP client ✓ Pure perl Message Queue ✓ I/O libraries (AnyEvent::*) ✓ DB libraries (AnyEvent::DBI) ✓ Job dispatcher (AE::Gearman)
  46. 46. Status 0.1.x on CPAN, considered beta AnyEvent server has bugs on Linux
  47. 47. Plans
  48. 48. Tatsumaki::Service Inspired by Google AppEngine Email/XMPP service Webhook pattern
  49. 49. XMPP/IRC Write Jabber/IRC bot as a web application
  50. 50. # see Tatsumaki-Service-XMPP/eg/translate.psgi package XMPPTranslateHandler; use base qw(Tatsumaki::Handler::XMPP); sub post { my $self = shift; my $msg = $self->xmpp_message; my $uri = “http://ajax.googleapis.com/...”; my $client = Tatsumaki::HTTPClient->new; $client->get($uri, $self->async_cb(sub { my $res = shift; my $r = JSON::decode_json($res->content); $msg->reply($r->{translatedText}); $self->finish; })); }
  51. 51. Standard Comet Interface a.k.a Stardust
  52. 52. Bayeux HTTP push relay
  53. 53. “Real” PubSub interface for Tatsumaki::MQ
  54. 54. Pluggable MQ using “real” MQ like ActiveMQ or RabbitMQ
  55. 55. DataStore interface using AnyEvent::DBI, Redis etc.
  56. 56. See Subfeedr for Redis integration http://github.com/miyagawa/Subfeedr
  57. 57. cpan> install Tatsumaki http://github.com/miyagawa/Tatsumaki irc://irc.perl.org/#plack
  58. 58. That’s it! Questions?

×