From ab68a26e84fcc01f084c5337e71db391e07c7954 Mon Sep 17 00:00:00 2001 From: Sergei Fedosov Date: Mon, 19 Jul 2021 14:42:30 +0300 Subject: [PATCH] Sync AnyEvent timer (brutal way) if timeskew more than 60 seconds. AnyEvent does not sync its timers with system time, so cron jobs that scheduled for particular time, shoots with time skew after wakeup from hibernate or suspend. And AnyEvent have no mechanism to sync its timers with local system time. The only way to "sync" timers is to remove and re-add watchers, so timers begin count time from beginning. To workaround timekeeping issue for AnyEvent::Timer::Cron let's add another time-based call back that will send SIGHUP to script if local system time differs from time counter more than 60 seconds. SIGHUP should trigger signal handler that remove all event watchers, re-read config and re-add event watchers effectively reloads config and re-launch timers for AnyEvent. --- i3status-anyevent | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/i3status-anyevent b/i3status-anyevent index 66e7d67..8d17f86 100644 --- a/i3status-anyevent +++ b/i3status-anyevent @@ -40,6 +40,9 @@ my $i3 = i3 (); my $done = AnyEvent->condvar; $i3->connect->recv or die 'Unable to connect to i3'; +# Local Time Counter +my $TC = time(); + # event pool my @EP; @@ -758,6 +761,20 @@ sub add_events () { } ) } + + # also we need workaround for timers after sleep or hibernate + push @EP, AnyEvent->timer ( + after => 60, # first invoke after 1 minute + interval => 60, # then invoke every 1 second + cb => sub { # the callback to invoke + $TC = $TC + 60; + my $timeskew = $TC - time (); + + if (($timeskew > 60) || ($timeskew < -60)) { + kill 'HUP', $$; + } + } + ); } return;