1 package OpenSRF::System;
2 use strict; use warnings;
5 use OpenSRF::Utils::Logger qw($logger);
6 use OpenSRF::Transport::Listener;
7 use OpenSRF::Transport;
9 use OpenSRF::EX qw/:try/;
10 use POSIX qw/setsid :sys_wait_h/;
11 use OpenSRF::Utils::Config;
12 use OpenSRF::Utils::SettingsParser;
13 use OpenSRF::Utils::SettingsClient;
14 use OpenSRF::Application;
17 my $bootstrap_config_file;
19 my( $self, $config ) = @_;
20 $bootstrap_config_file = $config;
27 sub load_bootstrap_config {
28 return if OpenSRF::Utils::Config->current;
30 die "Please provide a bootstrap config file to OpenSRF::System\n"
31 unless $bootstrap_config_file;
33 OpenSRF::Utils::Config->load(config_file => $bootstrap_config_file);
34 OpenSRF::Utils::JSON->register_class_hint(name => "OpenSRF::Application", hint => "method", type => "hash", strip => ['session']);
35 OpenSRF::Transport->message_envelope("OpenSRF::Transport::SlimJabber::MessageWrapper");
36 OpenSRF::Transport::PeerHandle->set_peer_client("OpenSRF::Transport::SlimJabber::PeerConnection");
37 OpenSRF::Application->server_class('client');
38 # Read in a shared portion of the config file
39 # for later use in log parameter redaction
40 $OpenSRF::Application::shared_conf = OpenSRF::Utils::Config->load(
41 'config_file' => OpenSRF::Utils::Config->current->FILE,
44 'base_path' => '/config/shared'
48 # ----------------------------------------------
49 # Bootstraps a single client connection.
50 # named params are 'config_file' and 'client_name'
51 sub bootstrap_client {
54 my $con = OpenSRF::Transport::PeerHandle->retrieve;
56 # flush the socket to force a non-blocking read
57 # and to clear out any unanticipated leftovers
58 eval { $con->flush_socket };
59 return if $con->connected;
65 $bootstrap_config_file =
66 $params{config_file} || $bootstrap_config_file;
68 my $app = $params{client_name} || "client";
70 load_bootstrap_config();
71 OpenSRF::Utils::Logger::set_config();
72 OpenSRF::Transport::PeerHandle->construct($app);
76 if (my $con = OpenSRF::Transport::PeerHandle->retrieve) {
77 return 1 if $con->connected;
83 my($class, $service, $pid_dir) = @_;
85 $0 = "OpenSRF Listener [$service]";
87 # temp connection to use for application initialization
88 OpenSRF::System->bootstrap_client(client_name => "system_client");
90 my $sclient = OpenSRF::Utils::SettingsClient->new;
91 my $getval = sub { $sclient->config_value(apps => $service => @_); };
93 my $impl = $getval->('implementation');
95 OpenSRF::Application::server_class($service);
96 OpenSRF::Application->application_implementation($impl);
97 OpenSRF::Utils::JSON->register_class_hint(name => $impl, hint => $service, type => 'hash');
98 OpenSRF::Application->application_implementation->initialize()
99 if (OpenSRF::Application->application_implementation->can('initialize'));
101 # kill the temp connection
102 OpenSRF::Transport::PeerHandle->retrieve->disconnect;
104 # if this service does not want stderr output, it will be redirected to /dev/null
105 my $disable_stderr = $getval->('disable_stderr') || '';
106 my $stderr_path = ($disable_stderr =~ /true/i) ? undef : $sclient->config_value(dirs => 'log');
108 my $server = OpenSRF::Server->new(
110 keepalive => $getval->('keepalive') || 5,
111 max_requests => $getval->(unix_config => 'max_requests') || 10000,
112 max_children => $getval->(unix_config => 'max_children') || 20,
113 min_children => $getval->(unix_config => 'min_children') || 1,
114 min_spare_children => $getval->(unix_config => 'min_spare_children'),
115 max_spare_children => $getval->(unix_config => 'max_spare_children'),
116 max_backlog_queue => $getval->(unix_config => 'max_backlog_queue'),
117 stderr_log_path => $stderr_path
121 eval { $server->run; };
122 # we only arrive here if the server died a painful death
123 $logger->error("server: died with error $@");
125 $logger->info("server: restarting after fatal crash...");