sashidhar ballagiri sashidhar ballagiri - 2 months ago 13
Perl Question

Perl + Possibility of mutiple ALRM signals

Scenario : Parent process shall spawn N worker children to load data to stage tables , and Parent frequently (every 15mins) invokes an StoredProc to move date from stage -> core

Idea : planning to setup an '$SIG{ALRM}' handler for every 15mins and invoke the StoreProc in the signal handler.

Seek suggestions if it's a good idea to setup Signal handlers to invoke a StoredProc whose execution time should be ~5mins , wondering what happens if the S/P runs beyond 15mins when another ALRM signal goes off.

Would this second signal get


  • queued to be handled later

  • gets lost completely

  • invoke another handler and S/P instance , while the previous handler is still
    running.


Answer

You're asking what happens if you have

$SIG{ALRM} = sub {
   alarm(15*60);
   call_stored_proc();
};

alarm(15*60);

and call_stored_proc takes longer than 15 minutes. Why didn't you just try it?

perl -e'
   use feature qw( say );

   my $slow = 2;
   my $done = 0;

   sub call_stored_proc {
      say sprintf "[%s] %s: %s", time, "call_stored_proc", "enter";
      sleep($slow ? 8 : 2);
      say sprintf "[%s] %s: %s", time, "call_stored_proc", "leave";
      $done = 1 if !$slow;
      --$slow;
   }

   $SIG{ALRM} = sub {
      say sprintf "[%s] %s: %s", time, "SIGALRM hander", "enter";
      say sprintf "[%s] %s: %s", time, "SIGALRM hander", "alarm set for ".(time+5);
      alarm(5);
      call_stored_proc();
      say sprintf "[%s] %s: %s", time, "SIGALRM hander", "leave";
   };

   say sprintf "[%s] %s: %s", time, "[root]", "alarm set for ".(time+5);
   alarm(5);
   sleep(1) while !$done;
'

Output:

[1474490009] [root]: alarm set for 1474490014
[1474490014] SIGALRM hander: enter
[1474490014] SIGALRM hander: alarm set for 1474490019
[1474490014] call_stored_proc: enter
[1474490022] call_stored_proc: leave
[1474490022] SIGALRM hander: leave
[1474490022] SIGALRM hander: enter
[1474490022] SIGALRM hander: alarm set for 1474490027
[1474490022] call_stored_proc: enter
[1474490030] call_stored_proc: leave
[1474490030] SIGALRM hander: leave
[1474490031] SIGALRM hander: enter
[1474490031] SIGALRM hander: alarm set for 1474490036
[1474490031] call_stored_proc: enter
[1474490033] call_stored_proc: leave
[1474490033] SIGALRM hander: leave

As you can see, call_stored_proc isn't interrupted. SIGALRM is suppressed until the SIGALRM handler returns.