From a12ebe7e3a222e78af976ffc3e1d6c80bd9d94a3 Mon Sep 17 00:00:00 2001 From: Mike Rylander Date: Fri, 25 Jul 2014 15:15:05 -0400 Subject: [PATCH] LP#1339190 Save state in the new world * and look in the right place for {ils} * do not exit on error, record it * pull just what we need, merge it later * do not freeze complex objects, and use FreezeThaw instead of Storable * And Only pass simple data through the fifo, pre-store the rest Signed-off-by: Mike Rylander Signed-off-by: Bill Erickson --- SIPServer.pm | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/SIPServer.pm b/SIPServer.pm index a3595a5..46f8996 100644 --- a/SIPServer.pm +++ b/SIPServer.pm @@ -42,7 +42,7 @@ use Sip::Checksum qw(checksum verify_cksum); use Sip::MsgType; use File::Queue; -use Storable qw(freeze thaw); +use FreezeThaw qw(freeze thaw); my $mp_fifo = File::Queue->new( File => "/tmp/SIPServer.mulitplex-fifo.$$" ); END { $mp_fifo->delete }; @@ -192,11 +192,16 @@ sub REAPER { my %active_connections; sub PERMAFROST { while (my $login = $mp_fifo->deq) { - $login = thaw($login); + ($login) = thaw($login); + + my $c = $$login{id}; if ($$login{success}) { - $active_connections{$$login{id}} = $login; + for my $p (keys %{ $$login{net_server_parts} }) { + $active_connections{$c}{net_server}{$p} = + $$login{net_server_parts}{$p}; + } } else { - delete $active_connections{$$login{id}}; + delete $active_connections{$c}; } } } @@ -261,7 +266,7 @@ sub mux_input { } # We stick this here, assuming success. Cleanup comes later via PERMAFROST(). - $active_connections{$conn_id} = { id => $conn_id, transport => $transport }; + $active_connections{$conn_id} = { id => $conn_id, transport => $transport, net_server => $self }; my $pid = fork(); if (!defined($pid) or $pid < 0) { @@ -277,21 +282,24 @@ sub mux_input { if ($@) { syslog('LOG_ERR', "ILS login error: $@"); $success = 0; - exit(0); - } - - # Evergreen, at least, needs a chance to clean up before forking for other requests - $self->{ils}->disconnect() if (UNIVERSAL::can($self->{ils},'disconnect')); + } else { + # Grab any state data for later + $self->{state} = $self->{ils}->state() if (UNIVERSAL::can($self->{ils},'state')); + + # Evergreen, at least, needs a chance to clean up before forking for other requests + $self->{ils}->disconnect() if (UNIVERSAL::can($self->{ils},'disconnect')); - # Stash the ILS module somewhere handy for later - $self->{ils} = ref($self->{ils}); + # Stash the ILS module somewhere handy for later + $self->{ils} = ref($self->{ils}); + } $mp_fifo->enq( freeze({ id => $conn_id, success => $success, - transport => $transport, - net_server => bless({%$self}, ref($self)) + net_server_parts => { + map { ($_ => $$self{$_}) } qw/ils state institution account/ + } }) ); @@ -312,7 +320,7 @@ sub mux_input { if ($pid == 0) { # in kid # build the connection we deleted after logging in - $self->{ils} = $active_connections{$conn_id}->{ils}->new($self->{institution}, $self->{account}, $active_connections{$conn_id}->{state}); + $self->{ils} = $self->{ils}->new($self->{institution}, $self->{account}, $self->{state}); if (!$self->{ils}) { syslog('LOG_ERR', "Unable to build ILS module in mux child"); -- 2.11.0