Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to gracefully stop a worker #63

Closed
stravid opened this issue Nov 3, 2015 · 2 comments
Closed

How to gracefully stop a worker #63

stravid opened this issue Nov 3, 2015 · 2 comments

Comments

@stravid
Copy link

stravid commented Nov 3, 2015

While there is plenty of information how to interact with Beanstalk I could not find details regarding how to implement a production grade worker with beaneater.

Mainly I'm concerned with how to stop a worker gracefully when, for example, it is restarted/stopped via systemd. As far as my understanding is I will want to let the worker finish it's job before I stop it. How can I accomplish this?

My current approach looks like this. It works if the worker is currently doing work, it will stop after the job. But if the worker is currently doing nothing it will stop only after the next job is processed. What am I doing wrong?

Thanks for your help.

#!/usr/bin/env ruby

require 'rubygems'
require 'bundler/setup'
require 'beaneater'

beanstalk = Beaneater.new '127.0.0.1:11300'
tube_name = "app.default"

beanstalk.jobs.register(tube_name) do |job|
  # Do the actual work.
end

trap 'SIGTERM' do
  beanstalk.jobs.stop!
end

trap 'SIGINT' do
  beanstalk.jobs.stop!
end

beanstalk.jobs.process!
beanstalk.close
@stravid
Copy link
Author

stravid commented Nov 7, 2015

I came up with another solution but stumbled into something like a deadlock. What am I doing wrong @nesquena ?

When I send a SIGTERM to the worker it tries to stop but the tube.put "-" somehow causes a deadlock? The output is "hi", "step 1", "step 2" but never reaches the next puts since it somehow hangs when it puts the job.

#!/usr/bin/env ruby

require "rubygems"
require "bundler/setup"
require "beaneater"

BEANSTALKD_URL = "localhost:11300"
CONTROL_TUBE_NAME = "control-#{1}"
DEFAULT_TUBE_NAME = "test"

class Worker
  def process!
    beanstalk = Beaneater.new BEANSTALKD_URL

    beanstalk.jobs.register DEFAULT_TUBE_NAME do |job|
      10.times do |n|
        sleep 1
        puts n
      end
    end

    beanstalk.jobs.register CONTROL_TUBE_NAME do |job|
      puts "stop"
      stop
    end

    beanstalk.jobs.process!
    beanstalk.close
  end

  def stop!
    puts "hi"
    beanstalk = Beaneater.new BEANSTALKD_URL
    puts "step 1"
    tube = beanstalk.tubes[CONTROL_TUBE_NAME]
    puts "step 2"
    tube.put "-"
    puts "step 3"

    beanstalk.close
    puts "bye"
  end

  private
  def stop
    raise Beaneater::AbortProcessingError
  end
end

worker = Worker.new

Signal.trap "INT"  do
  worker.stop!
end

Signal.trap "TERM" do
  worker.stop!
end

worker.process!

puts "good night"

@stravid
Copy link
Author

stravid commented Jul 7, 2016

I would still appreciate advice but can under stand that there is no time for that.

@stravid stravid closed this as completed Jul 7, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant