disque_jockey 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c49083bcd86ac5171c257bd78eeded4abbd5c99f
4
- data.tar.gz: 868ababcc280ffa34de1b8270c07b00c04bc299c
3
+ metadata.gz: e595757036b4f0fa828fcb9dda551db3f211ed7e
4
+ data.tar.gz: 81687ba961860e23ffd2b877b81166b8c8f3ea31
5
5
  SHA512:
6
- metadata.gz: 8fa502414a8a708a693cff041773bb2ae9201d7d0be70dd5fd5eafe2bedd3b6dc31852f7e9f1f516f2dffe52e7998e70923f49eb2a07817d3b768bc683dd632e
7
- data.tar.gz: 8dec61c2d6e36a1347147114f00e6290aa2cd2c2d4ae83b76124fdc4f68581e3727208c1f5554b2aa376fd76c212aa2e8e87ed0681bd0e2d1dc00a6f5058f43c
6
+ metadata.gz: 9bbd8ab91aba802d6f1c7364fe833eef0f20ee0813593cdad4fe3bb7c63c1508cf34db86f73530461283d5946c3520c472a5cfe48e0a1474c775c7b618972bd7
7
+ data.tar.gz: 4f294a19102ce434dd3c55d97425cde430680903e1241a2ef44d02c53dae2a7eecd9f8a796570d9cbba161ba0974889c2c732349ac8e5e807926f1c5d331c345
data/README.md CHANGED
@@ -63,6 +63,26 @@ disque_jockey start --env=production --daemonize=true --worker-groups=10 --node
63
63
  ````
64
64
 
65
65
  Messages successfully handled by a worker (ie no exceptions raised from the handle method) will be acknowledged and removed from the queue.
66
+ ## Worker Configuration
67
+ DisqueJockey::Worker implements some class methods that help you configure your worker. You call them the same way you call the `subscribe_to` method, at the top of your class.
68
+
69
+ ```ruby
70
+ require 'disque_jockey'
71
+ class HighlyConfiguredWorker < DisqueJockey::Worker
72
+ subscribe_to 'example-queue'
73
+ threads 7
74
+ fast_ack true
75
+ timeout 5
76
+
77
+ def handle(job)
78
+ logger.info("Peforming job: #{job}")
79
+ end
80
+ end
81
+ ```
82
+ - *Fast Acknowledgements*: call ````fast_ack true```` to use FASTACKs (https://github.com/antirez/disque#fast-acknowledges) in disque to acknowledge your messages. Please note that fast_ack will make it more likely you will process a job more than once in the event of a network partition. fast_ack is false by default.
83
+ - *Threads*: To devote more threads to your worker class use ````threads 5```` . Threads are set to two by default and have a maximum value of 10.
84
+ - *Timeout*: To set the number of seconds your worker will process a job until raising a TimeoutError, use ````timeout 45````. Timeout is set to 30 seconds by default and has a maximum value of 3600 seconds (one hour).
85
+
66
86
 
67
87
  ##Roadmap:
68
88
  DisqueJockey is not a currently a production-ready system, and there are a number of goals for it that have not been met yet.
@@ -13,10 +13,26 @@ module DisqueJockey
13
13
 
14
14
  def acknowledge(job_id)
15
15
  response = @client.call('ACKJOB', job_id)
16
- # If there is an error acking the job the Disque client
17
- # *returns* an error object but doesn't raise it,
18
- # so we raise it here ourselves.
16
+ raise_error_or_return_true(response)
17
+ end
18
+
19
+ def fast_acknowledge(job_id)
20
+ response = @client.call('FASTACK', job_id)
21
+ raise_error_or_return_true(response)
22
+ end
23
+
24
+ def publish(*args)
25
+ @client.push(*args)
26
+ end
27
+
28
+ private
29
+
30
+ # If there is an error acking the job the Disque client
31
+ # *returns* an error object but doesn't raise it,
32
+ # so we raise it here ourselves.
33
+ def raise_error_or_return_true(response)
19
34
  response.is_a?(RuntimeError) ? raise(response) : true
20
35
  end
36
+
21
37
  end
22
- end
38
+ end
@@ -1,3 +1,3 @@
1
1
  module DisqueJockey
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -11,13 +11,18 @@ module DisqueJockey
11
11
  end
12
12
 
13
13
  class << self
14
- attr_reader :queue_name, :thread_count, :timeout_seconds
14
+ attr_reader :queue_name, :thread_count, :timeout_seconds, :use_fast_ack
15
15
 
16
16
  # This worker class will subscribe to queue
17
17
  def subscribe_to(queue)
18
18
  @queue_name = queue
19
19
  end
20
20
 
21
+ # whehter to use Disque fast acknowledgements
22
+ def fast_ack(value)
23
+ @use_fast_ack = !!value
24
+ end
25
+
21
26
  # minimum number of worker instances of a given worker class.
22
27
  def threads(size)
23
28
  @thread_count = [[size, 1].max, 10].min
@@ -36,10 +41,11 @@ module DisqueJockey
36
41
  # these are the defaults
37
42
  type.threads 2
38
43
  type.timeout 30
44
+ type.fast_ack false
39
45
  # register the new worker type so we can start giving it jobs
40
46
  Supervisor.register_worker(type)
41
47
  end
42
48
  end
43
49
 
44
50
  end
45
- end
51
+ end
@@ -37,7 +37,7 @@ module DisqueJockey
37
37
  def handle_job(worker, job, job_id)
38
38
  begin
39
39
  Timeout::timeout(@worker_class.timeout_seconds) { worker.handle(job) }
40
- @broker.acknowledge(job_id)
40
+ @worker_class.use_fast_ack ? @broker.fast_acknowledge(job_id) : @broker.acknowledge(job_id)
41
41
  rescue StandardError => exception
42
42
  worker.log_exception(exception)
43
43
  # TODO: Need to implement retry logic
@@ -47,8 +47,8 @@ module DisqueJockey
47
47
  end
48
48
 
49
49
  def build_worker_pool
50
- @worker_class.thread_count.times { @pool << @worker_class.new(Logger) }
50
+ @worker_class.thread_count.times { @pool << @worker_class.new(Logger) }
51
51
  end
52
52
 
53
53
  end
54
- end
54
+ end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
  module DisqueJockey
3
3
  describe Broker do
4
- # Note: You actually have to run a Disque server
4
+ # Note: You actually have to run a Disque server
5
5
  # locally for these tests to pass
6
6
  before(:all) do
7
7
  begin
@@ -34,7 +34,7 @@ module DisqueJockey
34
34
  end
35
35
 
36
36
  describe '#acknowledge' do
37
- it "returns removes job from queue and returns true if it succeeds" do
37
+ it "removes job from queue and returns true if it succeeds" do
38
38
  @client.call('DEBUG', 'FLUSHALL')
39
39
  job_id = @client.push('test_queue', 'test job', 1000)
40
40
  expect(@client.call('QLEN', 'test_queue')).to eq 1
@@ -43,9 +43,34 @@ module DisqueJockey
43
43
  end
44
44
 
45
45
  it "raises an error for a bad job id" do
46
- expect{@broker.acknowledge('bad_id')}.to raise_error(RuntimeError)
46
+ expect{ @broker.acknowledge('bad_id') }.to raise_error(RuntimeError)
47
+ end
48
+ end
49
+
50
+ describe "#publish" do
51
+ it "publishes a job to Disque" do
52
+ test_queue = 'publish_test_queue'
53
+ test_job = 'job'
54
+ @broker.publish(test_queue, test_job, 1000)
55
+ fetched = @client.fetch(from: ['publish_test_queue']).first
56
+ expect(fetched.first).to eq test_queue
57
+ expect(fetched.last).to eq test_job
58
+ end
59
+ end
60
+
61
+ describe "#fast_acknowledge" do
62
+ it "raises an error for a bad job id" do
63
+ expect{@broker.fast_acknowledge('bad_id')}.to raise_error(RuntimeError)
64
+ end
65
+
66
+ it "acknowledges jobs" do
67
+ @client.call('DEBUG', 'FLUSHALL')
68
+ job_id = @client.push('test_queue', 'test job', 1000)
69
+ expect(@client.call('QLEN', 'test_queue')).to eq 1
70
+ expect(@broker.fast_acknowledge(job_id)).to eq true
71
+ expect(@client.call('QLEN', 'test_queue')).to eq 0
47
72
  end
48
73
  end
49
74
 
50
75
  end
51
- end
76
+ end
@@ -24,7 +24,13 @@ module DisqueJockey
24
24
 
25
25
  it "gives workers jobs to perform" do
26
26
  @mock_worker = double("Worker", handle: true)
27
- @mock_worker_class = double("WorkerClass", thread_count: 1, new: @mock_worker, timeout_seconds: 1, queue_name: 'q')
27
+ @mock_worker_class = double(
28
+ "WorkerClass",
29
+ thread_count: 1,
30
+ new: @mock_worker,
31
+ timeout_seconds: 1,
32
+ queue_name: 'q',
33
+ use_fast_ack: false)
28
34
  worker_pool = WorkerPool.new(@mock_worker_class)
29
35
  expect(@mock_worker).to receive(:handle)
30
36
  worker_pool.work!
@@ -36,9 +42,16 @@ module DisqueJockey
36
42
  end
37
43
 
38
44
  it "acknowledges jobs if they are processed without errors" do
45
+ SecondSpecWorker.fast_ack(false)
39
46
  expect_any_instance_of(Broker).to receive(:acknowledge).with('test_id').at_least(:once)
40
47
  WorkerPool.new(SecondSpecWorker).work!
41
48
  end
42
49
 
50
+ it "fast_acknowledges jobs if the worker uses fast_ack" do
51
+ SecondSpecWorker.fast_ack(true)
52
+ expect_any_instance_of(Broker).to receive(:fast_acknowledge).with('test_id').at_least(:once)
53
+ WorkerPool.new(SecondSpecWorker).work!
54
+ end
55
+
43
56
  end
44
- end
57
+ end
@@ -6,9 +6,10 @@ shared_context "worker setup" do
6
6
  subscribe_to "test"
7
7
  def handle(job); end
8
8
  end
9
-
9
+
10
10
  class SecondSpecWorker < DisqueJockey::Worker
11
11
  subscribe_to "other-test"
12
+ fast_ack true
12
13
  threads 1
13
14
  timeout 1
14
15
  def handle(job); end
@@ -6,8 +6,8 @@ describe DisqueJockey::Worker do
6
6
  include_context "worker setup"
7
7
 
8
8
  it "defines class methods" do
9
- [ :queue_name, :thread_count, :timeout_seconds,
10
- :subscribe_to, :timeout, :threads
9
+ [ :queue_name, :thread_count, :timeout_seconds,
10
+ :subscribe_to, :timeout, :threads, :fast_ack, :use_fast_ack
11
11
  ].each do |method|
12
12
  expect(DisqueJockey::Worker).to respond_to(method)
13
13
  end
@@ -24,26 +24,34 @@ describe DisqueJockey::Worker do
24
24
  end
25
25
 
26
26
  context "defaults" do
27
- it "sets a default for timeout" do
27
+ it "timeout is 30 seconds" do
28
28
  expect(SpecWorker.timeout_seconds).to be(30)
29
29
  end
30
30
 
31
- it "sets a default for thread_count" do
31
+ it "thread_count is 2" do
32
32
  expect(SpecWorker.thread_count).to be(2)
33
33
  end
34
+
35
+ it "use_fast_ack is false" do
36
+ expect(SpecWorker.use_fast_ack).to eq false
37
+ end
38
+
34
39
  end
35
40
 
36
41
  context "class methods"
37
42
  context "overrides" do
38
- it "allows overrides for timeout, and thread_count" do
43
+
44
+ it "allows overrides for timeout, threads, and fast_ack" do
45
+ # These traits are set in worker_shared_setup.rb
39
46
  expect(SecondSpecWorker.timeout_seconds).to be(1)
40
47
  expect(SecondSpecWorker.thread_count).to be(1)
48
+ expect(SecondSpecWorker.use_fast_ack).to be(true)
41
49
  end
42
50
  end
43
-
51
+
44
52
  context "instance methods"
45
53
  describe "#initialize" do
46
- before do
54
+ before do
47
55
  @logger = double(:logger, info: true, error: true, warn: true)
48
56
  allow(@logger).to receive(:new).and_return(@logger)
49
57
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: disque_jockey
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Devin Riley