Friday, September 17, 2010

Use Signal.trap("TERM") to support graceful shutdown

This server (http://github.com/wanli/avro_client/blob/master/test/sample_server.rb) doesn't trap any signals, so when you kill it with a TERM signal, it will shutdown even when it is in the middle of processing a request. We can make a few changes to support graceful shutdown.

First we need to setup signal traps:

  def setup_signal_traps
    Signal.trap("TERM") do
      @handler.stop if @handler
    end
  end

Then we need to add a variable @running and a method stop() to the handler:

  class SampleHandler
    def initialize(name, address, port)
      @name = name
      @ip_address = address
      @port = port
      # init running variable
      @running = true
    end
    def stop
      @running = false
    end
  end

Finally, we need to change the run() method to check the @running variable and don't wait for the select call forever:

  def run(&block)
    server = TCPServer.new(@ip_address, @port)
    sockets = [server]
    while @running
      # only wait for up to 1 sec at a time. 
      ready = select(sockets, nil, nil, 1)
      next unless ready
      readable = ready[0]
      readable.each do |socket|
        if socket == server
          client = server.accept
          sockets << client
        else
          begin
            handle(socket)
            yield
          rescue => e
            sockets.delete(socket)
            socket.close
          end
        end
      end
    end
  end

No comments:

Post a Comment