1 package OpenSRF::UnixServer;
2 use strict; use warnings;
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/;
11 use OpenSRF::Utils::SettingsClient;
13 use vars qw/@ISA $app/;
16 # XXX Need to add actual logging statements in the code
17 my $logger = "OpenSRF::Utils::Logger";
19 sub DESTROY { confess "Dying $$"; }
24 All inbound messages are passed on to the UnixServer for processing.
25 We take the data, close the Unix socket, and pass the data on to our abstract
28 Our purpose is to 'multiplex' a single TCP connection into multiple 'client' connections.
29 So when you pass data down the Unix socket to us, we have been preforked and waiting
30 to disperse new data among us.
34 sub app { return $app; }
39 my( $class, $app1 ) = @_;
41 throw OpenSRF::EX::InvalidArg( "UnixServer requires an app name to run" );
44 my $self = bless( {}, $class );
45 # my $client = OpenSRF::Utils::SettingsClient->new();
46 # if( $client->config_value("server_type") !~ /fork/i ||
47 # OpenSRF::Utils::Config->current->bootstrap->settings_config ) {
48 # warn "Calling hooks for non-prefork\n";
49 # $self->configure_hook();
50 # $self->child_init_hook();
57 =head2 process_request()
59 Takes the incoming data, closes the Unix socket and hands the data untouched
60 to the abstract process() method. This method is implemented in our subclasses.
68 while( $d = <STDIN> ) { $data .= $d; }
74 if( ! $data or ! defined( $data ) or $data eq "" ) {
75 throw OpenSRF::EX::Socket(
76 "Unix child received empty data from socket" );
79 if( ! close( $self->{server}->{client} ) ) {
80 $logger->debug( "Error closing Unix socket: $!", ERROR );
84 my $app = $self->app();
85 $logger->transport( "UnixServer for $app received $data", INTERNAL );
87 my $app_session = OpenSRF::Transport->handler( $self->app(), $data );
89 if(!ref($app_session)) {
90 $logger->transport( "Did not receive AppSession from transport handler, returning...", WARN );
95 my $client = OpenSRF::Utils::SettingsClient->new();
96 my $keepalive = $client->config_value("apps", $self->app(), "keepalive");
99 while( $app_session and $app_session->state and $app_session->state != $app_session->DISCONNECTED() and
100 $app_session->find( $app_session->session_id ) ) {
104 $logger->debug( "UnixServer calling queue_wait $keepalive", INTERNAL );
105 $app_session->queue_wait( $keepalive );
106 $logger->debug( "after queue wait $keepalive", INTERNAL );
109 if( ($after - $before) >= $keepalive ) {
111 my $res = OpenSRF::DomainObject::oilsConnectStatus->new(
112 status => "Disconnected on timeout",
113 statusCode => STATUS_TIMEOUT);
114 $app_session->status($res);
115 $app_session->state( $app_session->DISCONNECTED() );
122 while( $app_session && $app_session->queue_wait(0) ) {
123 $logger->debug( "Looping on zombies " . $x++ , DEBUG);
126 $logger->debug( "Timed out, disconnected, or auth failed", INFO );
127 $app_session->kill_me if ($app_session);
138 my $app = $self->app();
140 $0 = "OpenSRF master [$app]";
142 my $client = OpenSRF::Utils::SettingsClient->new();
143 $logger->transport("Max Req: " . $client->config_value("apps", $app, "unix_config", "max_requests" ), INFO );
145 my $min_servers = $client->config_value("apps", $app, "unix_config", "min_children" );
146 my $max_servers = $client->config_value("apps", $app, "unix_config", "max_children" );
147 my $min_spare = $client->config_value("apps", $app, "unix_config", "min_spare_children" );
148 my $max_spare = $client->config_value("apps", $app, "unix_config", "max_spare_children" );
149 my $max_requests = $client->config_value("apps", $app, "unix_config", "max_requests" );
150 my $log_file = join("/", $client->config_value("dirs", "log"),
151 $client->config_value("apps", $app, "unix_config", "unix_log" ));
152 my $port = join("/", $client->config_value("dirs", "sock"),
153 $client->config_value("apps", $app, "unix_config", "unix_sock" ));
154 my $pid_file = join("/", $client->config_value("dirs", "pid"),
155 $client->config_value("apps", $app, "unix_config", "unix_pid" ));
157 my $file = "/tmp/" . time . rand( $$ ) . "_$$";
158 my $file_string = "min_servers $min_servers\nmax_servers $max_servers\n" .
159 "min_spare_servers $min_spare\nmax_spare_servers $max_spare\n" .
160 "max_requests $max_requests\nlog_file $log_file\nproto unix\n" .
161 "port $port\npid_file $pid_file\nlog_level 3\n";
163 open F, "> $file" or die "Can't open $file : $!";
164 print F $file_string;
167 $self->run( 'conf_file' => $file );
174 my $app = $self->app;
177 OpenSRF::System->bootstrap_client( client_name => "system_client" );
179 $logger->debug( "Setting application implementaion for $app", DEBUG );
180 my $client = OpenSRF::Utils::SettingsClient->new();
181 my $imp = $client->config_value("apps", $app, "implementation");
182 OpenSRF::Application::server_class($app);
183 OpenSRF::Application->application_implementation( $imp );
184 JSON->register_class_hint( name => $imp, hint => $app, type => "hash" );
185 OpenSRF::Application->application_implementation->initialize()
186 if (OpenSRF::Application->application_implementation->can('initialize'));
188 if( $client->config_value("server_type") !~ /fork/i ) {
189 $self->child_init_hook();
192 my $con = OpenSRF::Transport::PeerHandle->retrieve;
197 return OpenSRF::Application->application_implementation;
200 sub child_finish_hook {
202 OpenSRF::AppSession->kill_client_session_cache;
205 sub child_init_hook {
207 $0 =~ s/master/drone/g;
209 if ($ENV{OPENSRF_PROFILE}) {
212 eval "use Devel::Profiler output_file => '/tmp/profiler_$file.out', buffer_size => 0;";
214 $logger->debug("Could not load Devel::Profiler: $@",ERROR);
216 $0 .= ' [PROFILING]';
217 $logger->debug("Running under Devel::Profiler", INFO);
223 # $logger->transport(
224 # "Creating PeerHandle from UnixServer child_init_hook", INTERNAL );
225 OpenSRF::Transport::PeerHandle->construct( $self->app() );
226 $logger->transport( "PeerHandle Created from UnixServer child_init_hook", INTERNAL );
228 OpenSRF::Application->application_implementation->child_init
229 if (OpenSRF::Application->application_implementation->can('child_init'));
230 return OpenSRF::Transport::PeerHandle->retrieve;