backburner 1.7.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +53 -4
  3. data/HOOKS.md +23 -14
  4. data/README.md +102 -23
  5. data/bin/backburner +1 -1
  6. data/lib/active_job/queue_adapters/backburner_adapter.rb +19 -5
  7. data/lib/backburner/cli.rb +1 -1
  8. data/lib/backburner/configuration.rb +7 -0
  9. data/lib/backburner/connection.rb +4 -2
  10. data/lib/backburner/enqueue_pool.rb +90 -0
  11. data/lib/backburner/helpers.rb +77 -22
  12. data/lib/backburner/job.rb +46 -7
  13. data/lib/backburner/logger.rb +9 -0
  14. data/lib/backburner/performable.rb +29 -4
  15. data/lib/backburner/queue.rb +37 -19
  16. data/lib/backburner/version.rb +1 -1
  17. data/lib/backburner/worker.rb +150 -25
  18. data/lib/backburner/workers/forking.rb +4 -2
  19. data/lib/backburner/workers/simple.rb +5 -0
  20. data/lib/backburner/workers/threading.rb +17 -7
  21. data/lib/backburner/workers/threads_on_fork.rb +59 -23
  22. data/lib/backburner.rb +7 -1
  23. metadata +40 -66
  24. data/.gitignore +0 -17
  25. data/.travis.yml +0 -29
  26. data/CONTRIBUTING.md +0 -37
  27. data/Gemfile +0 -4
  28. data/Rakefile +0 -17
  29. data/TODO +0 -4
  30. data/backburner.gemspec +0 -28
  31. data/circle.yml +0 -3
  32. data/examples/custom.rb +0 -25
  33. data/examples/demo.rb +0 -60
  34. data/examples/god.rb +0 -46
  35. data/examples/hooked.rb +0 -87
  36. data/examples/retried.rb +0 -31
  37. data/examples/simple.rb +0 -43
  38. data/examples/stress.rb +0 -31
  39. data/test/async_proxy_test.rb +0 -36
  40. data/test/back_burner_test.rb +0 -88
  41. data/test/connection_test.rb +0 -179
  42. data/test/fixtures/active_jobs.rb +0 -11
  43. data/test/fixtures/hooked.rb +0 -122
  44. data/test/fixtures/test_fork_jobs.rb +0 -72
  45. data/test/fixtures/test_forking_jobs.rb +0 -56
  46. data/test/fixtures/test_jobs.rb +0 -87
  47. data/test/fixtures/test_queue_settings.rb +0 -14
  48. data/test/helpers/templogger.rb +0 -22
  49. data/test/helpers_test.rb +0 -278
  50. data/test/hooks_test.rb +0 -112
  51. data/test/job_test.rb +0 -185
  52. data/test/logger_test.rb +0 -44
  53. data/test/performable_test.rb +0 -88
  54. data/test/queue_test.rb +0 -69
  55. data/test/test_helper.rb +0 -125
  56. data/test/worker_test.rb +0 -157
  57. data/test/workers/forking_worker_test.rb +0 -181
  58. data/test/workers/simple_worker_test.rb +0 -350
  59. data/test/workers/threading_worker_test.rb +0 -104
  60. data/test/workers/threads_on_fork_worker_test.rb +0 -484
data/.gitignore DELETED
@@ -1,17 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
data/.travis.yml DELETED
@@ -1,29 +0,0 @@
1
- # http://about.travis-ci.org/docs/user/build-configuration/
2
- rvm:
3
- - 1.9.3
4
- - 2.0.0
5
- - 2.1
6
- - 2.2
7
- - 2.3
8
- - 2.4
9
- - 2.5
10
- - rbx-2
11
- before_install:
12
- - curl -L https://github.com/kr/beanstalkd/archive/v1.9.tar.gz | tar xz -C /tmp
13
- - cd /tmp/beanstalkd-1.9/
14
- - make
15
- - ./beanstalkd &
16
- - cd $TRAVIS_BUILD_DIR
17
- - gem update --system
18
- - gem update bundler
19
- matrix:
20
- allow_failures:
21
- - rvm: rbx-2
22
- - rvm: 2.0.0
23
- script:
24
- - bundle exec rake test
25
- gemfile: Gemfile
26
- notifications:
27
- recipients:
28
- - nesquena@gmail.com
29
- - therealdave.myron@gmail.com
data/CONTRIBUTING.md DELETED
@@ -1,37 +0,0 @@
1
- We love pull requests. Here's a quick guide:
2
-
3
- 1. Fork the repo.
4
-
5
- 2. Run the tests. We only take pull requests with passing tests, and it's great
6
- to know that you have a clean slate: `bundle && rake test`
7
-
8
- 3. Add a test for your change. Only refactoring and documentation changes
9
- require no new tests. If you are adding functionality or fixing a bug, we need
10
- a test!
11
-
12
- 4. Make the test pass.
13
-
14
- 5. Push to your fork and submit a pull request.
15
-
16
- At this point you're waiting on us. We like to at least comment on, if not
17
- accept, pull requests within three business days (and, typically, one business
18
- day). We may suggest some changes or improvements or alternatives.
19
-
20
- Some things that will increase the chance that your pull request is accepted:
21
-
22
- * Use Rails idioms and helpers
23
- * Include tests that fail without your code, and pass with it
24
- * Update the documentation and README for anything affected by your contribution
25
-
26
- Syntax:
27
-
28
- * Two spaces, no tabs.
29
- * No trailing whitespace. Blank lines should not have any space.
30
- * Prefer &&/|| over and/or.
31
- * MyClass.my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
32
- * a = b and not a=b.
33
- * Follow the conventions you see used in the source already.
34
-
35
- And in case we didn't emphasize it enough: we love tests!
36
-
37
- NOTE: Adapted from https://raw.github.com/thoughtbot/factory_girl_rails/master/CONTRIBUTING.md
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in backburner.gemspec
4
- gemspec
data/Rakefile DELETED
@@ -1,17 +0,0 @@
1
- #!/usr/bin/env rake
2
- require "bundler/gem_tasks"
3
- require 'rake/testtask'
4
- # require 'yard'
5
-
6
- task :test do
7
- Rake::TestTask.new do |t|
8
- t.libs.push "lib"
9
- t.test_files = FileList[File.expand_path('../test/**/*_test.rb', __FILE__)]
10
- t.verbose = true
11
- end
12
- end
13
-
14
- task :default => :test
15
-
16
- # task :doc do
17
- # YARD::CLI::Yardoc.new.run
data/TODO DELETED
@@ -1,4 +0,0 @@
1
- - Custom front-end in sinatra for viewing beanstalk jobs
2
- - Refer to https://github.com/denniskuczynski/beanstalkd_view
3
- - Fork jobs to control memory
4
- - https://github.com/michaeldwan/stalker/commit/386267690a7c03e11d1a8b7b6f08b7c9c7cd2c0d
data/backburner.gemspec DELETED
@@ -1,28 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/backburner/version', __FILE__)
3
-
4
- Gem::Specification.new do |s|
5
- s.authors = ["Nathan Esquenazi"]
6
- s.email = ["nesquena@gmail.com"]
7
- s.description = %q{Beanstalk background job processing made easy}
8
- s.summary = %q{Reliable beanstalk background job processing made easy for Ruby and Sinatra}
9
- s.homepage = "http://github.com/nesquena/backburner"
10
-
11
- s.files = `git ls-files`.split($\)
12
- s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
- s.test_files = s.files.grep(%r{^(test|spec|features)/})
14
- s.name = "backburner"
15
- s.require_paths = ["lib"]
16
- s.version = Backburner::VERSION
17
- s.license = 'MIT'
18
-
19
- s.add_runtime_dependency 'beaneater', '~> 1.0'
20
- s.add_runtime_dependency 'dante', '> 0.1.5'
21
- s.add_runtime_dependency 'concurrent-ruby', '~> 1.0', '>= 1.0.1'
22
-
23
- s.add_development_dependency 'rake'
24
- s.add_development_dependency 'minitest', '5.1.0'
25
- s.add_development_dependency 'mocha'
26
- s.add_development_dependency 'activejob', '>= 6.0'
27
- s.add_development_dependency 'activesupport', '>= 6.0'
28
- end
data/circle.yml DELETED
@@ -1,3 +0,0 @@
1
- machine:
2
- services:
3
- - beanstalkd
data/examples/custom.rb DELETED
@@ -1,25 +0,0 @@
1
- $:.unshift "lib"
2
- require 'backburner'
3
-
4
- # Define ruby job
5
- class TestJob
6
- include Backburner::Queue
7
- # queue "test-job"
8
-
9
- def self.perform(value, user)
10
- puts "[TestJob] Running perform with args: [#{value}, #{user}]"
11
- end
12
- end
13
-
14
- # Configure Backburner
15
- Backburner.configure do |config|
16
- config.beanstalk_url = "beanstalk://127.0.0.1"
17
- config.tube_namespace = "demo.production"
18
- end
19
-
20
- # Enqueue tasks
21
- Backburner.enqueue TestJob, 5, 3
22
- Backburner.enqueue TestJob, 10, 6
23
-
24
- # Work tasks using threaded worker
25
- Backburner.work("test-job", :worker => Backburner::Workers::ThreadsOnFork)
data/examples/demo.rb DELETED
@@ -1,60 +0,0 @@
1
- $:.unshift "lib"
2
- require 'backburner'
3
-
4
- module Tester
5
- class TestJob
6
- include Backburner::Queue
7
- queue "test.job"
8
-
9
- def self.perform(value, user)
10
- p [value, user]
11
- end
12
- end
13
-
14
- class UserModel
15
- include Backburner::Performable
16
-
17
- attr_accessor :id, :name
18
-
19
- def self.first
20
- self.find(3, "John")
21
- end
22
-
23
- def self.find(id, name="Fetched")
24
- self.new(id, name)
25
- end
26
-
27
- def initialize(id, name)
28
- @id, @name = id, name
29
- end
30
-
31
- def hello(x, y)
32
- puts "Instance #{x} and #{y} and my id is #{id}"
33
- end
34
-
35
- def self.foo(x, y)
36
- puts "Class #{x} and #{y}"
37
- end
38
- end
39
- end
40
-
41
- # connection = Backburner::Connection.new("beanstalk://127.0.0.1")
42
-
43
- Backburner.configure do |config|
44
- config.beanstalk_url = "beanstalk://127.0.0.1"
45
- config.tube_namespace = "myblog.production"
46
- end
47
-
48
- # p Backburner.configuration.beanstalk_url
49
- # p Backburner::Worker.connection
50
-
51
- Backburner.enqueue Tester::TestJob, 5, 3
52
- Backburner.enqueue Tester::TestJob, 10, 6
53
- @user = Tester::UserModel.first
54
- @user.async.hello("foo", "bar")
55
- Tester::UserModel.async.foo("bar", "baz")
56
-
57
- Backburner.default_queues.concat([Tester::TestJob.queue, Tester::UserModel.queue])
58
- Backburner.work
59
- # Backburner.work("test.job")
60
- # Backburner.work("tester/user-model")
data/examples/god.rb DELETED
@@ -1,46 +0,0 @@
1
- God.watch do |w|
2
- w.name = "backburner-worker-1"
3
- w.dir = '/path/to/app/dir'
4
- w.env = { 'PADRINO_ENV' => 'production', 'QUEUES' => 'newsletter-sender,push-message' }
5
- w.group = 'backburner-workers'
6
- w.interval = 30.seconds
7
- w.start = "bundle exec rake -f Rakefile backburner:work"
8
- w.log = "/var/log/god/backburner-worker-1.log"
9
-
10
- # restart if memory gets too high
11
- w.transition(:up, :restart) do |on|
12
- on.condition(:memory_usage) do |c|
13
- c.above = 50.megabytes
14
- c.times = 3
15
- end
16
- end
17
-
18
- # determine the state on startup
19
- w.transition(:init, { true => :up, false => :start }) do |on|
20
- on.condition(:process_running) do |c|
21
- c.running = true
22
- end
23
- end
24
-
25
- # determine when process has finished starting
26
- w.transition([:start, :restart], :up) do |on|
27
- on.condition(:process_running) do |c|
28
- c.running = true
29
- c.interval = 5.seconds
30
- end
31
-
32
- # failsafe
33
- on.condition(:tries) do |c|
34
- c.times = 5
35
- c.transition = :start
36
- c.interval = 5.seconds
37
- end
38
- end
39
-
40
- # start if process is not running
41
- w.transition(:up, :start) do |on|
42
- on.condition(:process_running) do |c|
43
- c.running = false
44
- end
45
- end
46
- end
data/examples/hooked.rb DELETED
@@ -1,87 +0,0 @@
1
- $:.unshift "lib"
2
- require 'backburner'
3
-
4
- $fail = 0
5
- class User
6
- include Backburner::Performable
7
-
8
- # Called with the job args before a job is placed on the queue.
9
- # !! If the hook returns `false`, the job will not be placed on the queue.
10
- def self.before_enqueue_foo(*args)
11
- puts "[before_enqueue] Just about to enqueue #{self} with #{args.inspect}"
12
- end
13
-
14
- # Called with the job args after a job is placed on the queue.
15
- # !! Any exception raised propagates up to the code which queued the job.
16
- def self.after_enqueue_foo(*args)
17
- puts "[after_enqueue] Finished enqueuing #{self} with #{args.inspect}"
18
- end
19
-
20
- # Called with the job args before perform. If it raises
21
- # `Backburner::Job::DontPerform`, the job is aborted. Other exceptions
22
- # are treated like regular job exceptions.
23
- def self.before_perform_foo(*args)
24
- puts "[before_perform] Just about to perform #{self} with #{args.inspect}"
25
- end
26
-
27
- # Called with the job args after it performs. Uncaught
28
- # exceptions will be treated like regular job exceptions.
29
- def self.after_perform_foo(*args)
30
- puts "[after_perform] Just finished performing #{self} with #{args.inspect}"
31
- end
32
-
33
- # Called with the job args. It is expected to yield in order
34
- # to perform the job (but is not required to do so). It may handle exceptions
35
- # thrown by perform, but uncaught exceptions will be treated like regular job exceptions.
36
- def self.around_perform_bar(*args)
37
- puts "[around_perform_bar before] About to perform #{self} with #{args.inspect}"
38
- yield
39
- puts "[around_perform_bar after] Just after performing #{self} with #{args.inspect}"
40
- end
41
-
42
- # Called with the job args. It is expected to yield in order
43
- # to perform the job (but is not required to do so). It may handle exceptions
44
- # thrown by perform, but uncaught exceptions will be treated like regular job exceptions.
45
- def self.around_perform_cat(*args)
46
- puts "[around_perform_cat before] About to perform #{self} with #{args.inspect}"
47
- yield
48
- puts "[around_perform_cat after] Just after performing #{self} with #{args.inspect}"
49
- end
50
-
51
- # Called with the job args. It is expected to yield in order
52
- # to perform the job (but is not required to do so). It may handle exceptions
53
- # thrown by perform, but uncaught exceptions will be treated like regular job exceptions.
54
- def self.around_perform_foo(*args)
55
- puts "[around_perform_foo before] About to perform #{self} with #{args.inspect}"
56
- yield
57
- puts "[around_perform_foo after] Just after performing #{self} with #{args.inspect}"
58
- end
59
-
60
- # Called with the exception and job args if any exception occurs
61
- # while performing the job (or hooks).
62
- def self.on_failure_foo(ex, *args)
63
- puts "[on_failure] Failure #{ex.inspect} occurred for job #{self} with #{args.inspect}"
64
- end
65
-
66
- def self.foo
67
- $fail += 1
68
- raise "Fail!" if $fail == 1
69
- puts "This is the job running successfully!!"
70
- end
71
- end
72
-
73
- # Configure Backburner
74
- Backburner.configure do |config|
75
- config.beanstalk_url = "beanstalk://127.0.0.1"
76
- config.tube_namespace = "demo.production"
77
- config.on_error = lambda { |e| puts "HEY!!! #{e.class}" }
78
- config.max_job_retries = 1
79
- config.retry_delay = 0
80
- end
81
-
82
- # Enqueue tasks
83
- User.async.foo
84
-
85
- # Run work
86
- # Backburner.default_queues << "user"
87
- Backburner.work
data/examples/retried.rb DELETED
@@ -1,31 +0,0 @@
1
- $:.unshift "lib"
2
- require 'backburner'
3
-
4
- $error = 0
5
-
6
- class User
7
- include Backburner::Performable
8
- attr_accessor :id, :name
9
-
10
- def self.foo(x, y)
11
- $error += 1
12
- raise "fail #{$error}" unless $error > 3
13
- puts "User #foo args [#{x}, #{y}] Success!!"
14
- end
15
- end
16
-
17
- # Configure Backburner
18
- Backburner.configure do |config|
19
- config.beanstalk_url = "beanstalk://127.0.0.1"
20
- config.tube_namespace = "demo.production"
21
- config.on_error = lambda { |e| puts "HEY!!! #{e.class}" }
22
- config.max_job_retries = 3
23
- config.retry_delay = 0
24
- end
25
-
26
- # Enqueue tasks
27
- User.async(:queue => "retried").foo("bar", "baz")
28
-
29
- # Run work
30
- # Backburner.default_queues << "user"
31
- Backburner.work
data/examples/simple.rb DELETED
@@ -1,43 +0,0 @@
1
- $:.unshift "lib"
2
- require 'backburner'
3
-
4
- class User
5
- include Backburner::Performable
6
- attr_accessor :id, :name
7
-
8
- def self.first
9
- User.find(3, "John")
10
- end
11
-
12
- def self.find(id, name="Fetched")
13
- User.new(id, name)
14
- end
15
-
16
- def initialize(id, name)
17
- @id, @name = id, name
18
- end
19
-
20
- def hello(x, y)
21
- puts "User(id=#{id}) #hello args: [#{x}, #{y}] (Instance method)"
22
- end
23
-
24
- def self.foo(x, y)
25
- puts "User #foo args [#{x}, #{y}] (Class method)"
26
- end
27
- end
28
-
29
- # Configure Backburner
30
- Backburner.configure do |config|
31
- config.beanstalk_url = "beanstalk://127.0.0.1"
32
- config.tube_namespace = "demo.production"
33
- config.on_error = lambda { |e| puts "HEY!!! #{e.class}" }
34
- end
35
-
36
- # Enqueue tasks
37
- @user = User.first
38
- @user.async(:pri => 1000).hello("foo", "bar")
39
- User.async.foo("bar", "baz")
40
-
41
- # Run work
42
- # Backburner.default_queues << "user"
43
- Backburner.work
data/examples/stress.rb DELETED
@@ -1,31 +0,0 @@
1
- $:.unshift "lib"
2
- require 'backburner'
3
-
4
- $values = []
5
-
6
- # Define ruby job
7
- class TestJob
8
- include Backburner::Queue
9
- queue "test-job"
10
-
11
- def self.perform(value)
12
- puts "[TestJob] Running perform with args: [#{value}]"
13
- $values << value
14
- puts "#{$values.size} total jobs processed"
15
- end
16
- end
17
-
18
- # Configure Backburner
19
- Backburner.configure do |config|
20
- config.beanstalk_url = "beanstalk://127.0.0.1"
21
- config.tube_namespace = "demo.production"
22
- end
23
-
24
- # Enqueue tasks
25
- 1.upto(1000) do |i|
26
- Backburner.enqueue TestJob, i
27
- end
28
-
29
- # Work tasks using threads_on_fork worker
30
- # twitter tube will have 10 threads, garbage after 1000 executions and retry jobs 1 times.
31
- Backburner.work("test-job:10:100:1", :worker => Backburner::Workers::ThreadsOnFork)
@@ -1,36 +0,0 @@
1
- require File.expand_path('../test_helper', __FILE__)
2
-
3
- class AsyncUser; end
4
-
5
- describe "Backburner::AsyncProxy class" do
6
- before do
7
- Backburner.default_queues.clear
8
- clear_jobs!(Backburner.configuration.primary_queue)
9
- end
10
-
11
- describe "for method_missing enqueue" do
12
- should "enqueue job onto worker with no args" do
13
- @async = Backburner::AsyncProxy.new(AsyncUser, 10, :pri => 1000, :ttr => 100)
14
- @async.foo
15
- pop_one_job do |job, body|
16
- assert_equal "AsyncUser", body["class"]
17
- assert_equal [10, "foo"], body["args"]
18
- assert_equal 100, job.ttr
19
- assert_equal 1000, job.pri
20
- job.delete
21
- end
22
- end
23
-
24
- should "enqueue job onto worker with args" do
25
- @async = Backburner::AsyncProxy.new(AsyncUser, 10, :pri => 1000, :ttr => 100)
26
- @async.bar(1, 2, 3)
27
- pop_one_job do |job, body|
28
- assert_equal "AsyncUser", body["class"]
29
- assert_equal [10, "bar", 1, 2, 3], body["args"]
30
- assert_equal 100, job.ttr
31
- assert_equal 1000, job.pri
32
- job.delete
33
- end
34
- end
35
- end # method_missing
36
- end # AsyncProxy
@@ -1,88 +0,0 @@
1
- require File.expand_path('../test_helper', __FILE__)
2
-
3
- $backburner_sum = 0
4
- $backburner_numbers = []
5
-
6
- class TestBackburnerJob
7
- include Backburner::Queue
8
- queue "test.jobber"
9
-
10
- def self.perform(value, number)
11
- $backburner_sum += value
12
- $backburner_numbers << number
13
- end
14
- end
15
-
16
- class TestWorker < Backburner::Worker; end
17
-
18
- describe "Backburner module" do
19
- before { Backburner.default_queues.clear }
20
-
21
- describe "for enqueue method" do
22
- before do
23
- Backburner.enqueue TestBackburnerJob, 5, 6
24
- Backburner.enqueue TestBackburnerJob, 15, 10
25
- silenced(2) do
26
- worker = Backburner::Workers::Simple.new('test.jobber')
27
- worker.prepare
28
- 2.times { worker.work_one_job }
29
- end
30
- end
31
-
32
- it "can run jobs using #run method" do
33
- assert_equal 20, $backburner_sum
34
- assert_same_elements [6, 10], $backburner_numbers
35
- end
36
- end # enqueue
37
-
38
- describe "for work method" do
39
- it "invokes worker simple start" do
40
- Backburner::Workers::Simple.expects(:start).with(["foo", "bar"])
41
- Backburner.work("foo", "bar")
42
- end
43
-
44
- it "invokes other worker if specified in configuration" do
45
- Backburner.configure { |config| config.default_worker = TestWorker }
46
- TestWorker.expects(:start).with(["foo", "bar"])
47
- Backburner.work("foo", "bar")
48
- end
49
-
50
- it "invokes other worker if specified in work method as options" do
51
- TestWorker.expects(:start).with(["foo", "bar"])
52
- Backburner.work("foo", "bar", :worker => TestWorker)
53
- end
54
-
55
- it "invokes worker start with no args" do
56
- Backburner::Workers::Simple.expects(:start).with([])
57
- Backburner.work
58
- end
59
- end # work!
60
-
61
- describe "for configuration" do
62
- it "remembers the tube_namespace" do
63
- assert_equal "demo.test", Backburner.configuration.tube_namespace
64
- end
65
-
66
- it "remembers the namespace_separator" do
67
- assert_equal ".", Backburner.configuration.namespace_separator
68
- end
69
-
70
- it "disallows a reserved separator" do
71
- assert_raises RuntimeError do
72
- Backburner.configuration.namespace_separator = ':'
73
- end
74
- end
75
- end # configuration
76
-
77
- describe "for default_queues" do
78
- it "supports assignment" do
79
- Backburner.default_queues << "foo"
80
- Backburner.default_queues << "bar"
81
- assert_same_elements ["foo", "bar"], Backburner.default_queues
82
- end
83
- end
84
-
85
- after do
86
- Backburner.configure { |config| config.default_worker = Backburner::Workers::Simple }
87
- end
88
- end # Backburner