rubyrufus-schedulerdaemons

Rufus-Scheduler, DaemonKit and traps


I daemonized a Ruby scheduler script (using Rufus) with Rufus-Scheduler DaemonKit and I'm trying to trap the TERM or INT signals to have the application try to save state before quitting.

DaemonKit has its own trap_state (private) method and it catches the signal before the daemon script so even though I have this block, it doesn't do much.

DaemonKit::Application.running! do |config|

  surprise = Surprise.new(interval, frequency, false)
  surprise.start

  config.trap( 'SIGINT' ) do #tried INT and TERM as well
    puts 'Exiting'
    surprise.stop
    File.delete($lock)
  end
end

As a side effect (maybe a mistake in my implementation ?) after sigterm the .rufus lockfile is still there

The behavior on ctrl-c right now is this

[daemon-kit]: DaemonKit (0.3.1) booted, now running surprise
log writing failed. can't be called from trap context
[daemon-kit]: Running signal traps for INT
log writing failed. can't be called from trap context
[daemon-kit]: Running shutdown hooks
log writing failed. can't be called from trap context
[daemon-kit]: Shutting down surprise

The start method is a pretty simple schedule

def start

@scheduler = Rufus::Scheduler.new(:lockfile =>  $lock)

@scheduler.every '1d', :first_at => @first, :overlap => false do |job|
  ... # some work
end

 @scheduler.join
end

def stop
  # save state
  @scheduler.shutdown
end

Solution

  • So it's very simple, I need to configure the trap proc (or block in my case) BEFORE I run the scheduler in the start method. Not feeling very clever right about now, but the following code works as expected. For reference, the set_trap is private in DK but the public trap method overrides the defaults that come with the DK startup.

    DaemonKit::Application.running! do |config|
    
      surprise = Surprise.new(interval, frequency, false)
    
      config.trap("TERM") { surprise.stop }
      config.trap( "INT" ) { surprise.stop }
    
      surprise.start
    end
    

    Interestingly I saw this line on startup that I hadn't noticed before

    [daemon-kit]: Trapping SIGINT signals not supported on this platform
    

    INT and TERM both work though