1 package OpenSRF::Application;
3 use OpenSRF::AppSession;
4 use OpenSRF::DomainObject::oilsMethod;
5 use OpenSRF::DomainObject::oilsResponse qw/:status/;
6 use OpenSRF::Utils::Logger qw/:level/;
7 use Time::HiRes qw/time/;
8 use vars qw/$_app $log %_METHODS/;
9 use OpenSRF::EX qw/:try/;
13 $log = 'OpenSRF::Utils::Logger';
16 our @pending_requests;
18 sub application_implementation {
26 $log->error( "Error loading application_implementation: $app -> $@", ERROR);
35 my ($self, $session, $app_msg) = @_;
41 $log->debug( "In Application::handler()", DEBUG );
43 my $app = $self->application_implementation;
46 $log->debug( "Application is $app", DEBUG);
48 $log->debug( "Message is ".$app_msg->toString(1), INTERNAL);
51 if ($session->last_message_type eq 'REQUEST') {
52 $log->debug( "We got a REQUEST: ". $app_msg->method, INFO );
54 my $method_name = $app_msg->method;
55 $log->debug( " * Looking up $method_name inside $app", DEBUG);
57 my $method_proto = $session->last_message_protocol;
58 $log->debug( " * Method API Level [$method_proto]", DEBUG);
60 my $coderef = $app->method_lookup( $method_name, $method_proto );
63 $session->status( OpenSRF::DomainObject::oilsMethodException->new() );
67 $log->debug( " (we got coderef $coderef", DEBUG);
69 unless ($session->continue_request) {
71 OpenSRF::DomainObject::oilsConnectStatus->new(
72 statusCode => STATUS_REDIRECTED(),
73 status => 'Disconnect on max requests' ) );
79 my @args = $app_msg->params;
80 my $appreq = OpenSRF::AppRequest->new( $session );
82 $log->debug( "in_request = $in_request : [" . $appreq->threadTrace."]", DEBUG );
84 $log->debug( "Pushing onto pending requests: " . $appreq->threadTrace, DEBUG );
85 push @pending_requests, [ $appreq, \@args, $coderef ];
92 $log->debug( "Executing coderef for {$method_name -> ".join(', ', @args)."}", INTERNAL );
97 $resp = $coderef->run( $appreq, @args);
98 my $time = sprintf '%.3f', time() - $start;
99 $log->debug( "Method duration for {$method_name -> ".join(', ', @args)."}: ". $time, DEBUG );
101 $log->debug( "Calling respond_complete: ". $resp->toString(), INTERNAL );
102 $appreq->respond_complete( $resp );
104 $appreq->status( OpenSRF::DomainObject::oilsConnectStatus->new(
105 statusCode => STATUS_COMPLETE(),
106 status => 'Request Complete' ) );
110 $e = $e->{-text} || $e->message if (ref $e);
111 my $sess_id = $session->session_id;
113 OpenSRF::DomainObject::oilsMethodException->new(
114 statusCode => STATUS_INTERNALSERVERERROR(),
115 status => " *** Call to [$method_name] failed for session ".
116 "[$sess_id], thread trace [".$appreq->threadTrace."]:\n".$e
123 # ----------------------------------------------
126 # XXX may need this later
127 # $_->[1] = 1 for (@OpenSRF::AppSession::_CLIENT_CACHE);
131 $log->debug( "Pending Requests: " . scalar(@pending_requests), INTERNAL );
133 # cycle through queued requests
134 while( my $aref = shift @pending_requests ) {
139 my $response = $aref->[2]->run( $aref->[0], @{$aref->[1]} );
140 my $time = sprintf '%.3f', time - $start;
141 $log->debug( "Method duration for {[".$aref->[2]->name." -> ".join(', ',@{$aref->[1]}).'}: '.$time, DEBUG );
143 $appreq = $aref->[0];
144 if( ref( $response ) ) {
145 $log->debug( "Calling respond_complete: ". $response->toString(), INTERNAL );
146 $appreq->respond_complete( $response );
148 $appreq->status( OpenSRF::DomainObject::oilsConnectStatus->new(
149 statusCode => STATUS_COMPLETE(),
150 status => 'Request Complete' ) );
152 $log->debug( "Executed: " . $appreq->threadTrace, DEBUG );
156 OpenSRF::DomainObject::oilsMethodException->new(
157 statusCode => STATUS_INTERNALSERVERERROR(),
158 status => "Call to [".$aref->[2]->name."] faild: ".$e->{-text}
167 my $res = OpenSRF::DomainObject::oilsMethodException->new;
168 $session->send('ERROR', $res);
173 $log->debug( "Pushing ". $app_msg->toString ." onto queue", INTERNAL );
174 $session->push_queue([ $app_msg, $session->last_threadTrace ]);
177 $session->last_message_type('');
178 $session->last_message_protocol('');
183 sub register_method {
185 my $app = ref($self) || $self;
188 throw OpenSRF::DomainObject::oilsMethodException unless ($args{method});
190 $args{protocol} ||= 1;
191 $args{api_name} ||= $app . '.' . $args{method};
192 $args{code} ||= \&{$app . '::' . $args{method}};
194 $_METHODS{$args{api_name}} = bless \%args => $app;
203 my $class = ref($self) || $self;
205 $log->debug("Specialized lookup of [$method] in [$class]", INTERNAL);
207 if (exists $_METHODS{$method}) {
208 return $_METHODS{$method} if ($_METHODS{$method}{protocol} == $proto);
216 $self->{code}->($self, @_);