NAME

Continuity - Abstract away statelessness of HTTP using continuations, for stateful Web applications

SYNOPSIS

#!/usr/bin/perl
use strict;
use Coro;

use Continuity;
my $server = new Continuity;

sub main {
  my $request = shift;
  $request->next; # Get the first actual request
  # must do a substr to chop the leading '/'
  my $name = substr($request->url->path, 1) || 'World';
  $request->print("Hello, $name!");
  $request = $request->next();
  $name = substr($request->url->path, 1) || 'World';
  $request->print("Hello to you too, $name!");
}

$server->loop;

DESCRIPTION

Continuity is a library (not a framework) to simplify Web applications. Each session is written and runs as if it were a persistant application, and is able to request additional input at any time without exiting. Applications call a method, $request-next>, which temporarily gives up control of the CPU and then (eventually) returns the next request. Put another way, coroutines make the HTTP Web appear stateful.

Beyond the basic idea of using coroutines to build Web apps, some logic is required to decide how to associate incoming requests with coroutines, and logic is required to glue the daemonized application server to the Web. Sample implementations of both are provided (specifically, an adapter to run a dedicated Webserver built out of HTTP::Request is included), and these implementations are useful for many situations and are subclassable.

This is ALPHA software, and feedback/code is welcomed. See the Wiki in the references below for things the authors are unhappy with.

METHODS

$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:

adapter -- defaults to an instance of Continuity::Adapt::HttpDaemon
mapper -- defaults to an instance of Continuity::Mapper
docroot -- defaults to .
callback -- defaults to \&::main
staticp -- defaults to sub { 0 }, used to indicate whether any request is for static content
debug -- defaults to 4 at the moment ;)

$server->loop()

Calls Coro::Event::loop (through exportation). This never returns!

Internal Structure

For the curious or the brave, here is an ASCII diagram of how the pieces fit:

+---------+      +---------+     +--------+                         
| Browser | <--> | Adaptor | --> | Mapper |                         
+---------+      +---------+     +--------+                         
                      ^              |                              
                      |              |                              
+---------------------+              |                              
|      +-------------------+---------+----------+          
|      |                   |                    |              
|      V                   V                    V              
|    +---------+         +---------+          +---------+         
|    | Session |         | Session |          | Session |            
|    | Request |         | Request |          | Request |         
|    | Queue   |         | Queue   |          | Queue   |         
|    |    |    |         |    |    |          |    |    |        
|    |    V    |         |    V    |          |    V    |         
|    +---------+         +---------+          +---------+          
|      |                   |                    |             
|      V                   V                    V              
|  +-----+   +------+   +-----+   +------+   +-----+   +------+
|  | Cur |<->| Your |   | Cur |<->| Your |   | Cur |<->| Your |
|  | Req |   | Code |   | Req |   | Code |   | Req |   | Code |
|  +-----+   +------+   +-----+   +------+   +-----+   +------+
|     |                    |                    |
|     V                    V                    V
+-----+--------------------+--------------------+

** "Cur Req" == "Current Request"

Basically, the Adaptor accepts requests from the browser, hands them off to the Mapper, which then queues them into the correct session queue (or creates a new queue).

When Your Code calls "$request->next" the Current Request overwrites itself with the next item in the queue (or waits until there is one).

Most of the time you will have pretty empty queues -- they are mostly there for safety, in case you have a lot of incoming requests and running sessions.

SEE ALSO

Website/Wiki: http://continuity.tlt42.org/

Continuity::Adapt::HttpDaemon, Continuity::Mapper, Continuity::Adapt::HttpDaemon::Request, Coro.

AUTHOR

Brock Wilcox <awwaiid@thelackthereof.org> - http://thelackthereof.org/
Scott Walters <scott@slowass.net> - http://slowass.net/

COPYRIGHT

Copyright (c) 2004-2007 Brock Wilcox <awwaiid@thelackthereof.org>. All
rights reserved.  This program is free software; you can redistribute it
and/or modify it under the same terms as Perl itself.