]> git.evergreen-ils.org Git - OpenSRF.git/blob - src/perlmods/OpenSRF/UnixServer.pm
some sanity checking, syntax error fixups
[OpenSRF.git] / src / perlmods / OpenSRF / UnixServer.pm
1 package OpenSRF::UnixServer;
2 use strict; use warnings;
3 use base qw/OpenSRF/;
4 use OpenSRF::EX;
5 use OpenSRF::Utils::Logger qw(:level);
6 use OpenSRF::Transport::PeerHandle;
7 use OpenSRF::Application;
8 use OpenSRF::AppSession;
9 use OpenSRF::DomainObject::oilsResponse qw/:status/;
10 use OpenSRF::System;
11 use vars qw/@ISA/;
12 use Carp;
13
14 # XXX Need to add actual logging statements in the code
15 my $logger = "OpenSRF::Utils::Logger";
16
17 sub DESTROY { confess "Dying $$"; }
18
19 =head1 What am I
20
21 All inbound messages are passed on to the UnixServer for processing.
22 We take the data, close the Unix socket, and pass the data on to our abstract
23 'process()' method.  
24
25 Our purpose is to 'multiplex' a single TCP connection into multiple 'client' connections.
26 So when you pass data down the Unix socket to us, we have been preforked and waiting
27 to disperse new data among us.
28
29 =cut
30
31 {
32         my $app;
33         sub app { return $app; }
34
35         sub new {
36                 my( $class, $app1 ) = @_;
37                 if( ! $app1 ) {
38                         throw OpenSRF::EX::InvalidArg( "UnixServer requires an app name to run" );
39                 }
40                 $app = $app1;
41                 my $self = bless( {}, $class );
42                 if( OpenSRF::Utils::Config->current->system->server_type !~ /fork/i ) {
43                         $self->child_init_hook();
44                 }
45                 return $self;
46         }
47
48 }
49
50 =head2 process_request()
51
52 Takes the incoming data, closes the Unix socket and hands the data untouched 
53 to the abstract process() method.  This method is implemented in our subclasses.
54
55 =cut
56
57 sub process_request {
58
59         my $self = shift;
60         my $data; my $d;
61         while( $d = <STDIN> ) { $data .= $d; }
62
63         $0 = "$0*";
64
65
66         if( ! $data or ! defined( $data ) or $data eq "" ) {
67                 throw OpenSRF::EX::Socket(
68                                 "Unix child received empty data from socket" );
69         }
70
71         if( ! close( $self->{server}->{client} ) ) {
72                 $logger->debug( "Error closing Unix socket: $!", ERROR );
73         }
74
75
76         my $app = $self->app();
77         $logger->transport( "UnixServer for $app received $data", INTERNAL );
78
79         my $app_session = OpenSRF::Transport->handler( $self->app(), $data );
80         my $config = OpenSRF::Utils::Config->current;
81
82
83         my $keepalive = OpenSRF::Utils::Config->current->system->keep_alive;
84
85         my $req_counter = 0;
86         while( $app_session->state and $app_session->state != $app_session->DISCONNECTED() and
87                         $app_session->find( $app_session->session_id ) ) {
88                 
89
90                 my $before = time;
91                 $logger->transport( "UnixServer calling queue_wait $keepalive", INTERNAL );
92                 $app_session->queue_wait( $keepalive );
93                 my $after = time;
94
95                 if( ($after - $before) >= $keepalive ) { 
96
97                         my $res = OpenSRF::DomainObject::oilsConnectStatus->new(
98                                                                         status => "Disconnected on timeout",
99                                                                         statusCode => STATUS_TIMEOUT);
100                         $app_session->status($res);
101                         $app_session->state( $app_session->DISCONNECTED() );
102                         last;
103                 }
104
105         }
106
107         my $x = 0;
108         while( 1 ) {
109                 $logger->transport( "Looping on zombies " . $x++ , DEBUG);
110                 last unless ( $app_session->queue_wait(0));
111         }
112
113         $logger->transport( "Timed out, disconnected, or auth failed", INFO );
114         $app_session->kill_me;
115
116         $0 =~ s/\*//g;
117
118                 
119 }
120
121
122 sub serve {
123         my( $self ) = @_;
124         my $config = OpenSRF::Utils::Config->current;
125         my $app = $self->app();
126         my $conf_base =  $config->dirs->conf_dir;
127         my $conf = join( "/", $conf_base, $config->unix_conf->$app );
128         $logger->transport( 
129                         "Running UnixServer as @OpenSRF::UnixServer::ISA for $app with conf file: $conf", INTERNAL );
130         $self->run( 'conf_file' => $conf );
131 }
132
133 sub configure_hook {
134         my $self = shift;
135         my $app = $self->app;
136         my $config = OpenSRF::Utils::Config->current;
137
138         $logger->debug( "Setting application implementaion for $app", DEBUG );
139
140         OpenSRF::Application->application_implementation( $config->application_implementation->$app );
141         OpenSRF::Application->application_implementation->initialize()
142                 if (OpenSRF::Application->application_implementation->can('initialize'));
143         return OpenSRF::Application->application_implementation;
144 }
145
146 sub child_finish_hook {
147         my $self = shift;
148         OpenSRF::AppSession->kill_client_session_cache;
149 }
150
151 sub child_init_hook { 
152
153         my $self = shift;
154         $logger->transport( 
155                         "Creating PeerHandle from UnixServer child_init_hook", INTERNAL );
156         OpenSRF::Transport::PeerHandle->construct( $self->app() );
157         my $peer_handle = OpenSRF::System::bootstrap_client("system_client");
158         OpenSRF::Application->application_implementation->child_init
159                 if (OpenSRF::Application->application_implementation->can('child_init'));
160         return $peer_handle;
161
162 }
163
164 1;
165