try to improve error/close/timeout restarting
authorDirk Koopman <djk@tobit.co.uk>
Thu, 6 Aug 2015 20:45:23 +0000 (21:45 +0100)
committerDirk Koopman <djk@tobit.co.uk>
Thu, 6 Aug 2015 20:45:23 +0000 (21:45 +0100)
loop.pl

diff --git a/loop.pl b/loop.pl
index 7abba2d70408881c61ace5f86599da67f4d3e8ea..bdc06d6e01f6e87d8d0d93f2573b3784706af69e 100755 (executable)
--- a/loop.pl
+++ b/loop.pl
@@ -33,7 +33,8 @@ my $nlcount;
 my $state = "ready";
 my $buf;
 my $dbg;
-my $ser;                                                       # the serial port Mojo::IOLoop::Stream
+our $ser;                                                      # the serial port Mojo::IOLoop::Stream
+our $ob;                                                       # the Serial Port filehandle
 my $last_min_h;
 my $last_hour_h;
 
@@ -96,7 +97,7 @@ $bar_trend{60} = "Rising Rapidly";
 
 our $ending = 0;
 
-$SIG{TERM} = $SIG{INT} = sub {++$ending; Mojo::IOLoop->stop;};
+$SIG{TERM} = $SIG{INT} = sub {$ending = 1; Mojo::IOLoop->stop;};
 $SIG{HUP} = 'IGNORE';
 
 
@@ -164,18 +165,22 @@ dbg sprintf("last5days = %d last10mins = %d", scalar @last5daysh, scalar @last10
 
 sysopen(R, $randomfn, 0) or die "cannot open $randomfn $!\n";
 my $rs;
-sysread(R, $rs, 32) or die "not enough randomness available\n";
+sysread(R, $rs, 8) or die "not enough randomness available\n";
 close R;
 
 app->secrets([qw(Here's something that's really seakrett), $rs]);
 
 our $dlog = SMGLog->new("day");
+$did = Mojo::IOLoop->recurring(1 => sub {$dlog->flushall});
+
 dbg "before next tick";
 Mojo::IOLoop->next_tick(sub { loop() });       
 dbg "before app start";
 app->start;
 dbg "after app start";
 
+doclose();
+
 write_ld();
 $dataf->close if $dataf;
 undef $dataf;
@@ -185,7 +190,7 @@ undef $dataf;
 cycle_loop_data_files();
 
 dbg '***';
-dbg "*** ending $0";
+dbg "*** ending $0 (\$ending = $ending)";
 dbg '***';
 
 exit 0;
@@ -197,9 +202,8 @@ sub loop
        dbg "last_min: " . scalar gmtime($ld->{last_min});
        dbg "last_hour: " . scalar gmtime($ld->{last_hour});
        
-       $did = Mojo::IOLoop->recurring(1 => sub {$dlog->flushall});
-       
-       do_reopen($devname);
+       $ser = doopen($devname);
+       start_loop() if $ser;
 }
 
 
@@ -243,8 +247,7 @@ sub start_loop
        undef $tid;
        $tid = Mojo::IOLoop->recurring(0.6 => sub {
                                                                           if (++$nlcount > 10) {
-                                                                                  dbg "\\n count > 10, closing connection" if isdbg 'chan';
-                                                                                  do_reopen($devname);
+                                                                                  doclose();
                                                                                   return;
                                                                           }
                                                                           dbg "writing $nlcount \\n" if isdbg 'state'; 
@@ -259,47 +262,68 @@ sub chgstate
        $state = $_[0];
 }
 
-sub do_reopen
-{
-       my $name = shift;
-       dbg "do reopen on '$name' ending $ending";
-       unless ($ending) {
-               $ser = do_open($name);
-               start_loop();
-               chgstate('');
-               $nlcount = 0;
-               Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
-       }
-}
+my $closing;
 
-sub do_open
+sub doopen
 {
        my $name = shift;
 
-       $ser->close if $ser;
-       undef $ser;
-
-       my $ob = Serial->new($name, 19200) || die "$name $!\n";
+    $ob = Serial->new($name, 19200) || die "$name $!\n";
        dbg "streaming $name fileno(" . fileno($ob) . ")" if isdbg 'chan';
        
        my $ser = Mojo::IOLoop::Stream->new($ob);
-       $ser->on(error=>sub {dbg "serial $_[1]"; do_reopen($name) unless $ending});
-       $ser->on(close=>sub {dbg "serial closing"; do_reopen($name) unless $ending});
-       $ser->on(timeout=>sub {dbg "serial timeout";});
+       $ser->on(error=>sub {dbg "error serial $_[1]"; doclose();});
+       $ser->on(close=>sub {dbg "event close";  doclose();});
+       $ser->on(timeout=>sub {dbg "event serial timeout"; doclose();});
        $ser->on(read=>sub {on_read(@_)});
        $ser->start;
 
+    $rid = Mojo::IOLoop->recurring($poll_interval => sub {
+                                       start_loop() if !$state;
+                                   });
+
+       chgstate('');
+       $nlcount = 0;
+       
+       return $ser;
+}
+
+sub doclose
+{
+       return if $closing++;
+       
+       dbg "serial port closing" if $ser || $ob;
+       if ($ser) {
+               $ser->stop;
+               $ser->close;
+               undef $ser;
+       }
+       if ($ob) {
+               $ob->close();
+               undef $ob;
+       }
        Mojo::IOLoop->remove($tid) if $tid;
        undef $tid;
        Mojo::IOLoop->remove($rid) if $rid;
        undef $rid;
-       $rid = Mojo::IOLoop->recurring($poll_interval => sub {
-                                                                          start_loop() if !$state;
-                                                                  });
+
+    if (Mojo::IOLoop->is_running && $ending == 0) {
+               Mojo::IOLoop->delay(
+                                                       sub {
+                                                               my $delay = shift;
+                                                               Mojo::IOLoop->timer(5 => $delay->begin);
+                                                               dbg "Waiting 5 seconds before opening serial port";
+                                                        },
+
+                                                       sub {
+                                                               dbg "Opening Serial port";
+                                                               $ser = doopen($devname);
+                                                               $closing = 0;
+                                                       }
+                                                  )->wait;
+       }
        chgstate('');
        $nlcount = 0;
-       
-       return $ser;
 }
 
 my @min;