Skip to main content
YAPC::Asia 2009                     2009/09/10




                 dann
          techmemo@gmail.com

Angelos           github.com/dann          dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
request
            Engine                                    response
                                              (                  with Plack)
                                                  miyagawa++, tokuhirom++



                                                    Component
          Dispatcher                                 Manager
            URL to Controller
                                                     Component load & search
Angelos                         github.com/dann                                dann
Angelos   github.com/dann   dann
sub build_engine {
  my $self         = shift;
  my $request_handler = $self->request_handler;
  $request_handler ||= $self->build_request_handler;
    return Angelos::PSGI::Engine->new(
       interface => {                    Server Gateway
          module => $self->server,
          ....
       },
       psgi_handler => $request_handler,
    );                            Server Gateway
}
                                           psgi handler
Angelos                  github.com/dann                  dann
use Mouse;
use Angelos::Types qw( ServerGateway );
 
has 'interface' => (
                                     Server Gateway
    is => 'ro',
    isa => ServerGateway,
    coerce => 1,
);                                          Server Gateway
                                          psgi handler (coderef)
has 'psgi_handler' => ( is => 'rw', );
 
sub run {
    my $self = shift;
    $self->interface->run( $self->psgi_handler );
}
 Angelos                   github.com/dann                     dann
package Angelos::PSGI::ServerGatewayBuilder;
use strict;
use warnings;
use Plack::Loader;                 Plack::Loader
                                     ServerGateway
sub build {
  my ( $class, $module, $args ) = @_;
  my $server_gateway = Plack::Loader->load( $module,
%{$args} );
  $server_gateway;
}

 Angelos                 github.com/dann             dann
PSGI   env

...                               WAF Request
sub {                            (with Plack::Request)
          my $env = shift;
          my $req = Angelos::Request->new($env);
          my $res = $self->handle_request($req);
          my $psgi_res = $self->finalize_response($res);
          return $psgi_res;
}
...                      PSGI   response



Angelos                   github.com/dann                 dann
sub handle_request {                         req Dsipatcher
  my ( $self, $req ) = @_;
      eval { $self->DISPATCH($req); };
      if ( my $e = Exception::Class->caught() ) {
          $self->HANDLE_EXCEPTION($e);
      }
      # response
      return $self->context->res;
}

    Angelos                github.com/dann                    dann
request Dispatcher
sub DISPATCH {
  my ( $self, $req ) = @_;               dispatch

    my $dispatch = $self->dispatcher->dispatch($req);
    ...
    # dispatch
    $dispatch->run;
    # response
    $c->res;
}

Angelos                github.com/dann                       dann
<URL to Controller>
sub dispatch {                           HTTP::Router request
  my ( $self, $request ) = @_;                      route
                                         (ikasam_a++)
  my $match = $self->router->match($request);

  my $dispatch = $self->dispatch_class->new( match =>
$match );
  return $dispatch;
}                                   dispatch



Angelos                github.com/dann                        dann
# matching         controller
my $controller = $match->params->{controller};
my $controller_instance = $self-
>find_controller_instance(                Component Manager
    { context => $c,                      Controller
      controller => $controller,
    }
);                                       Controller action
...
$controller_instance->_dispatch_action( $action,
$params );

 Angelos               github.com/dann                       dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
sub _dispatch_action {
  my ( $self, $action, $params ) = @_; Hook
  ...
      eval { $self->ACTION( $self->context, $action, $params ); };
      ...
}




    Angelos                   github.com/dann                        dann
before 'ACTION' => sub {
   my ( $self, $c, $action, $params ) = @_;
   $self->__action_start_time( time() );
};
after 'ACTION' => sub {
   my ( $self, $c, $action, $params ) = @_;
   $self->__action_end_time( time() );
   my $elapsed = $self->__action_end_time - $self-
>__action_start_time;
   my $message
      = "action processing time:naction: $action ntime : $elapsed
secsn";
   $self->log->info($message);
};


 Angelos                    github.com/dann                      dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann
Angelos   github.com/dann   dann