#!/usr/bin/env ruby require 'thin' require 'resque' require 'redis' # we don't want to stop the entire EM reactor when we stop a web server # & @connections data type changed in thin 1.5.1 module Thin # see https://github.com/flapjack/flapjack/issues/169 class Request class EqlTempfile < ::Tempfile def eql?(obj) obj.equal?(self) && (obj == self) end end def move_body_to_tempfile current_body = @body current_body.rewind @body = Thin::Request::EqlTempfile.new(BODY_TMPFILE) @body.binmode @body << current_body.read @env[RACK_INPUT] = @body end end module Backends class Base def stop! @running = false @stopping = false # EventMachine.stop if EventMachine.reactor_running? case @connections when Array @connections.each { |connection| connection.close_connection } when Hash @connections.each_value { |connection| connection.close_connection } end close end end end end # Resque is really designed around a multiprocess model, so we here we # stub some that behaviour away. module Resque class Worker def procline(string) # $0 = "resque-#{Resque::Version}: #{string}" # log! $0 end # Redefining the entire method to stop the direct access to $0 :( def work(interval = 5.0, &block) interval = Float(interval) # $0 = "resque: Starting" startup loop do break if shutdown? if not paused? and job = reserve log "got: #{job.inspect}" job.worker = self run_hook :before_fork, job working_on job if @child = fork srand # Reseeding procline "Forked #{@child} at #{Time.now.to_i}" Process.wait(@child) else unregister_signal_handlers if !@cant_fork && term_child procline "Processing #{job.queue} since #{Time.now.to_i}" redis.client.reconnect if !@cant_fork # Don't share connection with parent perform(job, &block) exit! unless @cant_fork end done_working @child = nil else break if interval.zero? log! "Sleeping for #{interval} seconds" procline paused? ? "Paused" : "Waiting for #{@queues.join(',')}" sleep interval end end unregister_worker rescue Exception => exception unregister_worker(exception) end end end # As Redis::Future objects inherit from BasicObject, it's difficult to # distinguish between them and other objects in collected data from # pipelined queries. # # (One alternative would be to put other values in Futures ourselves, and # evaluate everything...) class Redis class Future def class ::Redis::Future end end end