Continuity

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

    from the $request object beyond this introduction.

      sub main {
        my $request = shift;
        # ...
      }

    Outputting to the client (that is, sending text to the browser) is done
    by calling the "$request->print(...)" method, rather than the plain
    "print" used in CGI.pm applications.

      $request->print("Hello, guvne'<br>");
      $request->print("'ow ya been?");

    HTTP query parameters (both GET and POST) are also gotten through the
    $request handle, by calling "$p = $request->param('x')", just like in
    CGI.pm.

      # If they go to http://webapp/?x=7
      my $input = $request->param('x');
      # now $input is 7

    Once you have output your HTML, call "$request->next" to wait for the
    next response from the client browser. While waiting other sessions will
    handle other requests, allowing the single process to handle many
    simultaneous sessions.

      $request->print("Name: <form><input type=text name=n></form>");
      $request->next;                   # <-- this is where we suspend execution
      my $name = $request->param('n');  # <-- start here once they submit

    Anything declared lexically (using my) inside of "main" is private to
    the session, and anything you make global is available to all sessions.
    When "main" returns the session is terminated, so that another request
    from the same client will get a new session. Only one continuation is
    ever executing at a given time, so there is no immediate need to worry
    about locking shared global variables when modifying them.

ADVANCED USAGE
    Merely using the above code can completely change the way you think
    about web application infrastructure. But why stop there? Here are a few
    more things to ponder.

  Coro::Event
    Since Continuity is based on Coro, we also get to use Coro::Event. This
    means that you can set timers to wake a continuation up after a while,
    or you can have inner-continuation signaling by watch-events on shared
    variables.

  Multiple sessions per-user
    For AJAX applications, we've found it handy to give each user multiple
    sessions. In the chat-ajax-push demo each user gets a session for
    sending messages, and a session for receiving them. The receiving
    session uses a long-running request (aka COMET) and watches the globally
    shared chat message log. When a new message is put into the log, it
    pushes to all of the ajax listeners.

  Lexical storage and callback links
    Don't forget about those pretty little lexicals you have at your
    disposal. Taking a hint from the Seaside folks, instead of regular links
    you could have callbacks that trigger a anonymous subs. Your code could
    look like:

      use Continuity;
      use strict;
      my @callbacks;
      my $callback_count;
      Continuity->new->loop;
      sub gen_link {
        my ($text, $code) = @_;
        $callbacks[$callback_count++] = $code;
        return qq{<a href="?cb=$callback_count">$text</a>};
      }
      sub process_links {
        my $request = shift;
        my $cb = $request->param('cb');
        if(exists $callbacks[$cb]) {
          $callbacks[$cb]->($request);
          delete $callbacks[$cb];
        }
      }
      sub main {
        my $request = shift;
        my $x;
        my $link1 = gen_link('This is a link to stuff' => sub { $x = 7  });
        my $link2 = gen_link('This is another link'    => sub { $x = 42 });
        $request->print($link1, $link2);
        $request->next;
        process_links($request);
        $request->print("\$x is now: $x");
      }

  Scaling
    To scale a Continuity-based application beyond a single process you need
    to investigate the keywords "session affinity". The Seaside folks have a
    few articles on various experiments they've done for scaling, see the
    wiki for links and ideas. Note, however, that premature optimization is
    evil. We shouldn't even be talking about this.

EXTENDING AND CUSTOMIZING
    This library is designed to be extensible but have good defaults. There
    are two important components which you can extend or replace.

    The Adapter, such as the default Continuity::Adapt::HttpDaemon, actually
    makes the HTTP connections with the client web broswer. If you want to
    use FastCGI or even a non-HTTP protocol, then you will use or create an
    Adapter.

    The Mapper, such as the default Continuity::Mapper, identifies incoming
    requests from The Adapter and maps them to instances of your program. In
    other words, Mappers keep track of sessions, figuring out which requests
    belong to which session. The default mapper can identify sessions based
    on any combination of cookie, ip address, and URL path. Override The
    Mapper to create alternative session identification and management.

METHODS
    The main instance of a continuity server really only has two methods,
    "new" and "loop". These are used at the top of your program to do setup
    and start the server. Please look at Continuity::Request for
    documentation on the $request object that is passed to each session in
    your application.

  $server = Continuity->new(...)
    The "Continuity" object wires together an Adapter and a mapper. Creating
    the "Continuity" object gives you the defaults wired together, or if
    user-supplied instances are provided, it wires those together.

    Arguments:

    *   "callback" -- coderef of the main application to run persistantly
        for each unique visitor -- defaults to "\&::main"

    *   "adapter" -- defaults to an instance of
        "Continuity::Adapt::HttpDaemon"

    *   "mapper" -- defaults to an instance of "Continuity::Mapper"

    *   "docroot" -- defaults to "."



( run in 0.577 second using v1.01-cache-2.11-cpan-39bf76dae61 )