evented-gearman-ruby 1.0.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.
- data/.gitignore +1 -0
- data/HOWTO +146 -0
- data/LICENSE +20 -0
- data/README +4 -0
- data/Rakefile +41 -0
- data/TODO +8 -0
- data/VERSION.yml +4 -0
- data/evented-gearman-ruby.gemspec +110 -0
- data/examples/calculus_client.rb +41 -0
- data/examples/calculus_worker.rb +42 -0
- data/examples/client.rb +19 -0
- data/examples/client_background.rb +14 -0
- data/examples/client_data.rb +16 -0
- data/examples/client_exception.rb +17 -0
- data/examples/client_prefix.rb +15 -0
- data/examples/evented_client.rb +23 -0
- data/examples/evented_worker.rb +26 -0
- data/examples/gearman_environment.sh +25 -0
- data/examples/scale_image.rb +30 -0
- data/examples/scale_image_worker.rb +34 -0
- data/examples/server.rb +15 -0
- data/examples/worker.rb +23 -0
- data/examples/worker_data.rb +16 -0
- data/examples/worker_exception.rb +14 -0
- data/examples/worker_prefix.rb +25 -0
- data/lib/gearman.rb +29 -0
- data/lib/gearman/client.rb +80 -0
- data/lib/gearman/evented/client.rb +99 -0
- data/lib/gearman/evented/reactor.rb +86 -0
- data/lib/gearman/evented/worker.rb +118 -0
- data/lib/gearman/job.rb +38 -0
- data/lib/gearman/protocol.rb +110 -0
- data/lib/gearman/server.rb +94 -0
- data/lib/gearman/task.rb +99 -0
- data/lib/gearman/taskset.rb +11 -0
- data/lib/gearman/util.rb +52 -0
- data/lib/gearman/worker.rb +39 -0
- data/test/basic_integration_test.rb +121 -0
- data/test/crash_test.rb +69 -0
- data/test/job_test.rb +30 -0
- data/test/protocol_test.rb +132 -0
- data/test/test_helper.rb +31 -0
- data/test/util_test.rb +12 -0
- data/test/worker_test.rb +45 -0
- metadata +149 -0
data/lib/gearman/task.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
module Gearman
|
2
|
+
class Task
|
3
|
+
|
4
|
+
attr_reader :name, :payload, :retries_done
|
5
|
+
attr_accessor :retries, :priority, :background, :poll_status_interval
|
6
|
+
|
7
|
+
def initialize(name, payload = nil, opts = {})
|
8
|
+
@name = name.to_s
|
9
|
+
@payload = payload || ''
|
10
|
+
@priority = opts.delete(:priority).to_sym rescue nil
|
11
|
+
@background = opts.delete(:background) ? true : false
|
12
|
+
|
13
|
+
@retries_done = 0
|
14
|
+
@retries = opts.delete(:retries) || 0
|
15
|
+
|
16
|
+
@poll_status_interval = opts.delete(:poll_status_interval)
|
17
|
+
@uniq = opts.has_key?(:uuid) ? opts.delete(:uuid) : `uuidgen`.strip
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Set a block of code to be executed when this task completes
|
22
|
+
# successfully. The returned data will be passed to the block.
|
23
|
+
def on_complete(&f)
|
24
|
+
@on_complete = f
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Set a block of code to be executed when this task fails.
|
29
|
+
def on_fail(&f)
|
30
|
+
@on_fail = f
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Set a block of code to be executed when this task is retried after
|
35
|
+
# failing. The number of retries that have been attempted (including the
|
36
|
+
# current one) will be passed to the block.
|
37
|
+
def on_retry(&f)
|
38
|
+
@on_retry = f
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Set a block of code to be executed when a remote exception is sent by a worker.
|
43
|
+
# The block will receive the message of the exception passed from the worker.
|
44
|
+
# The user can return true for retrying or false to mark it as finished
|
45
|
+
#
|
46
|
+
# NOTE: this is actually deprecated, cf. https://bugs.launchpad.net/gearmand/+bug/405732
|
47
|
+
#
|
48
|
+
def on_exception(&f)
|
49
|
+
@on_exception = f
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# Set a block of code to be executed when we receive a status update for
|
54
|
+
# this task. The block will receive two arguments, a numerator and
|
55
|
+
# denominator describing the task's status.
|
56
|
+
def on_status(&f)
|
57
|
+
@on_status = f
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Set a block of code to be executed when we receive a warning from a worker.
|
62
|
+
# It is recommended for workers to send work_warning, followed by work_fail if
|
63
|
+
# an exception occurs on their side. Don't expect this behavior from workers NOT
|
64
|
+
# using this very library ATM, though. (cf. https://bugs.launchpad.net/gearmand/+bug/405732)
|
65
|
+
def on_warning(&f)
|
66
|
+
@on_warning = f
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# Set a block of code to be executed when we receive a (partial) data packet for this task.
|
71
|
+
# The data received will be passed as an argument to the block.
|
72
|
+
def on_data(&f)
|
73
|
+
@on_data = f
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Record a failure and check whether we should be retried.
|
78
|
+
#
|
79
|
+
# @return true if we should be resubmitted; false otherwise
|
80
|
+
def should_retry?
|
81
|
+
return false if @retries_done >= @retries
|
82
|
+
@retries_done += 1
|
83
|
+
true
|
84
|
+
end
|
85
|
+
|
86
|
+
def background?
|
87
|
+
background
|
88
|
+
end
|
89
|
+
|
90
|
+
def dispatch(event, *args)
|
91
|
+
callback = instance_variable_get("@#{event}".to_sym)
|
92
|
+
callback.call(*args) if callback
|
93
|
+
end
|
94
|
+
|
95
|
+
def hash
|
96
|
+
@uniq
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/gearman/util.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'socket'
|
4
|
+
require 'time'
|
5
|
+
|
6
|
+
module Gearman
|
7
|
+
|
8
|
+
class ServerDownException < Exception; end
|
9
|
+
|
10
|
+
# = Util
|
11
|
+
#
|
12
|
+
# == Description
|
13
|
+
# Static helper methods and data used by other classes.
|
14
|
+
class Util
|
15
|
+
|
16
|
+
@@debug = false
|
17
|
+
|
18
|
+
##
|
19
|
+
# Enable or disable debugging output (off by default).
|
20
|
+
#
|
21
|
+
# @param v print debugging output
|
22
|
+
def Util.debug=(v)
|
23
|
+
@@debug = v
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Log a message if debugging is enabled.
|
28
|
+
#
|
29
|
+
# @param str message to log
|
30
|
+
def Util.log(str, force=false)
|
31
|
+
puts "#{Time.now.strftime '%Y-%m-%d %H:%M:%S'} #{str}" if force or @@debug
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Log a message no matter what.
|
36
|
+
#
|
37
|
+
# @param str message to log
|
38
|
+
def Util.err(str)
|
39
|
+
log(str, true)
|
40
|
+
end
|
41
|
+
|
42
|
+
def Util.ability_name_with_prefix(prefix,name)
|
43
|
+
"#{prefix}\t#{name}"
|
44
|
+
end
|
45
|
+
|
46
|
+
class << self
|
47
|
+
alias :ability_name_for_perl :ability_name_with_prefix
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Gearman
|
2
|
+
class Worker
|
3
|
+
|
4
|
+
attr_reader :abilities
|
5
|
+
|
6
|
+
def initialize(job_servers, opts = {})
|
7
|
+
@reactors = []
|
8
|
+
@abilities = {}
|
9
|
+
|
10
|
+
@job_servers = Array[*job_servers]
|
11
|
+
|
12
|
+
@opts = opts
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_ability(name, timeout = nil, &f)
|
16
|
+
remove_ability(name) if @abilities.has_key?(name)
|
17
|
+
@abilities[name] = { :callback => f, :timeout => timeout }
|
18
|
+
end
|
19
|
+
|
20
|
+
def remove_ability(name)
|
21
|
+
@abilities.delete(name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def has_ability?(name)
|
25
|
+
@abilities.has_key?(name)
|
26
|
+
end
|
27
|
+
|
28
|
+
def work
|
29
|
+
EM.run do
|
30
|
+
@job_servers.each do |hostport|
|
31
|
+
host, port = hostport.split(":")
|
32
|
+
opts = { :abilities => @abilities }.merge(@opts)
|
33
|
+
Gearman::Evented::WorkerReactor.connect(host, port, opts)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class BasicIntegrationTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
start_gearmand
|
7
|
+
@client = Gearman::Client.new("localhost:4730")
|
8
|
+
@worker = Gearman::Worker.new("localhost:4730")
|
9
|
+
Thread.new { EM.run } unless EM.reactor_running?
|
10
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
stop_gearmand
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_ping_job
|
17
|
+
response = nil
|
18
|
+
|
19
|
+
@worker.add_ability("pingpong") {|data, job| "pong" }
|
20
|
+
@worker.work
|
21
|
+
|
22
|
+
task = Gearman::Task.new("pingpong", "ping")
|
23
|
+
|
24
|
+
task.on_complete {|res| response = res }
|
25
|
+
@client.run task
|
26
|
+
|
27
|
+
assert_equal "pong", response
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_exception_in_worker
|
31
|
+
warning_given = nil
|
32
|
+
failed = false
|
33
|
+
|
34
|
+
task = Gearman::Task.new("crash", "doesntmatter")
|
35
|
+
|
36
|
+
@worker.add_ability("crash") {|data, job| raise Exception.new("BOOM!") }
|
37
|
+
@worker.work
|
38
|
+
|
39
|
+
task.on_warning {|warning| warning_given = warning }
|
40
|
+
task.on_fail { failed = true}
|
41
|
+
@client.run task
|
42
|
+
|
43
|
+
assert_not_nil warning_given
|
44
|
+
assert_equal true, failed
|
45
|
+
assert_equal 0, task.retries_done
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_should_be_able_to_retry_on_worker_exception
|
49
|
+
retry_callback_called = false
|
50
|
+
fail_count = 0
|
51
|
+
|
52
|
+
# Gearman::Util.debug = true
|
53
|
+
task = Gearman::Task.new("crash", "doesntmatter", :retries => 1)
|
54
|
+
|
55
|
+
@worker.add_ability("crash") {|data, job| raise Exception.new("BOOM!") }
|
56
|
+
@worker.work
|
57
|
+
|
58
|
+
task.on_retry {|i| retry_callback_called = true }
|
59
|
+
task.on_fail { fail_count += 1 }
|
60
|
+
@client.run task
|
61
|
+
|
62
|
+
assert_equal true, retry_callback_called
|
63
|
+
assert_equal 1, task.retries_done
|
64
|
+
assert_equal 1, fail_count
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_chunked_response
|
68
|
+
chunks_received = 0
|
69
|
+
|
70
|
+
@worker.add_ability("chunked") do |data, job|
|
71
|
+
5.times {|i| job.send_partial("chunk #{i}") }
|
72
|
+
end
|
73
|
+
@worker.work
|
74
|
+
|
75
|
+
task = Gearman::Task.new("chunked")
|
76
|
+
task.on_data do |data|
|
77
|
+
assert_match /^chunk \d/, data
|
78
|
+
chunks_received += 1
|
79
|
+
end
|
80
|
+
@client.run task
|
81
|
+
|
82
|
+
assert_equal 5, chunks_received
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_background
|
86
|
+
status_received = false
|
87
|
+
|
88
|
+
@worker.add_ability("fireandforget") {|data, job| "this goes to /dev/null" }
|
89
|
+
@worker.work
|
90
|
+
|
91
|
+
task = Gearman::Task.new('fireandforget', 'background', :background => true, :poll_status_interval => 0.1)
|
92
|
+
task.on_complete {|d| flunk "on_complete should never be called for a background job!" }
|
93
|
+
task.on_status {|d| status_received = true }
|
94
|
+
@client.run task
|
95
|
+
|
96
|
+
assert_equal true, status_received
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_non_blocking_run
|
100
|
+
@worker.add_ability("foo") {|data, job| "foo: #{data}" }
|
101
|
+
@worker.work
|
102
|
+
|
103
|
+
task1_complete = false
|
104
|
+
task2_complete = false
|
105
|
+
|
106
|
+
task1 = Gearman::Task.new("foo", 1)
|
107
|
+
task1.on_complete {|d| task1_complete = true}
|
108
|
+
@client.run task1, nil, true
|
109
|
+
|
110
|
+
assert_equal false, task1_complete
|
111
|
+
|
112
|
+
task2 = Gearman::Task.new("foo", 2)
|
113
|
+
task2.on_complete {|d| task2_complete = true}
|
114
|
+
@client.run task2, nil, true
|
115
|
+
|
116
|
+
Thread.new { sleep 0.1 }.join
|
117
|
+
|
118
|
+
assert_equal true, task1_complete
|
119
|
+
assert_equal true, task2_complete
|
120
|
+
end
|
121
|
+
end
|
data/test/crash_test.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
# Gearman::Util.debug = true
|
4
|
+
class CrashTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
teardown_gearmands
|
8
|
+
Thread.new { EM.run } unless EM.reactor_running?
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
teardown_gearmands
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_worker_should_reconnect_if_gearmand_goes_away
|
16
|
+
start_gearmand
|
17
|
+
worker = Gearman::Worker.new("localhost:4730", :reconnect_sec => 1)
|
18
|
+
worker.add_ability("foo") {|data, job| "noop!" }
|
19
|
+
|
20
|
+
response = nil
|
21
|
+
|
22
|
+
worker.work
|
23
|
+
stop_gearmand
|
24
|
+
start_gearmand
|
25
|
+
|
26
|
+
task = Gearman::Task.new("foo", "ping")
|
27
|
+
task.on_complete {|res| response = res }
|
28
|
+
Gearman::Client.new("localhost:4730").run task
|
29
|
+
|
30
|
+
assert_equal "noop!", response
|
31
|
+
stop_gearmand
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_client_and_worker_should_use_failover_gearmand_if_primary_is_not_available
|
35
|
+
start_gearmand 4731
|
36
|
+
|
37
|
+
worker = Gearman::Worker.new(["localhost:4730", "localhost:4731"], :reconnect_sec => 1)
|
38
|
+
worker.add_ability("foo") {|data, job| "noop!" }
|
39
|
+
|
40
|
+
response = nil
|
41
|
+
worker.work
|
42
|
+
task = Gearman::Task.new("foo", "ping")
|
43
|
+
task.on_complete {|res| response = res }
|
44
|
+
Gearman::Client.new(["localhost:4730", "localhost:4731"]).run task
|
45
|
+
|
46
|
+
assert_equal "noop!", response
|
47
|
+
stop_gearmand 4731
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_client_and_worker_should_switch_to_failover_gearmand_if_primary_goes_down
|
51
|
+
start_gearmand 4730
|
52
|
+
start_gearmand 4731
|
53
|
+
|
54
|
+
worker = Gearman::Worker.new(["localhost:4730", "localhost:4731"], :reconnect_sec => 1)
|
55
|
+
worker.add_ability("foo") {|data, job| "noop!" }
|
56
|
+
|
57
|
+
response = nil
|
58
|
+
worker.work
|
59
|
+
|
60
|
+
stop_gearmand 4730
|
61
|
+
|
62
|
+
task = Gearman::Task.new("foo", "ping")
|
63
|
+
task.on_complete {|res| response = res }
|
64
|
+
Gearman::Client.new(["localhost:4730", "localhost:4731"]).run task
|
65
|
+
|
66
|
+
assert_equal "noop!", response
|
67
|
+
stop_gearmand 4731
|
68
|
+
end
|
69
|
+
end
|
data/test/job_test.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class JobTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@handle = "H:foo:1"
|
7
|
+
@mock_client = mock()
|
8
|
+
@job = Gearman::Job.new(@mock_client, @handle)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_supports_report_status
|
12
|
+
@mock_client.expects(:send).with(:work_status, [@handle, 1, 5].join("\0"))
|
13
|
+
@job.report_status(1, 5)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_supports_send_partial
|
17
|
+
@mock_client.expects(:send).with(:work_data, [@handle, "bar"].join("\0"))
|
18
|
+
@job.send_partial("bar")
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_supports_send_data
|
22
|
+
@mock_client.expects(:send).with(:work_data, [@handle, "bar"].join("\0"))
|
23
|
+
@job.send_data("bar")
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_supports_report_warning
|
27
|
+
@mock_client.expects(:send).with(:work_warning, [@handle, "danger"].join("\0"))
|
28
|
+
@job.report_warning("danger")
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class ProtocolTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_encode_request
|
6
|
+
payload = ["foo", "123", "bar"].join("\0")
|
7
|
+
expected = "\0REQ" + [Gearman::Protocol::COMMANDS_NUMERIC[:submit_job], payload.size].pack("NN") + payload
|
8
|
+
assert_equal expected, Gearman::Protocol.encode_request(:submit_job, payload)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_decode_response
|
12
|
+
response = "\0RES" + [Gearman::Protocol::COMMANDS_NUMERIC[:work_data], 3].pack("NN") + handle + "\0foo"
|
13
|
+
packets = Gearman::Protocol.decode_response(response)
|
14
|
+
assert_equal 1, packets.size
|
15
|
+
assert_equal [:work_data, "H:wrk.acme:1", "foo"], packets.first
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_decodes_multiple_response_packets
|
19
|
+
response = "\0RES" + [Gearman::Protocol::COMMANDS_NUMERIC[:work_data], 3].pack("NN") + handle + "\0foo"
|
20
|
+
response << "\0RES" + [Gearman::Protocol::COMMANDS_NUMERIC[:work_data], 3].pack("NN") + handle + "\0bar"
|
21
|
+
response << "\0RES" + [Gearman::Protocol::COMMANDS_NUMERIC[:work_data], 3].pack("NN") + handle + "\0baz"
|
22
|
+
|
23
|
+
assert_equal 3, Gearman::Protocol.decode_response(response).size
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_response_packet
|
27
|
+
packet = [:work_data, handle, "foo"]
|
28
|
+
assert_equal packet, Gearman::Protocol.response_packet(*packet)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_decodes_work_complete
|
32
|
+
data = "esta complet"
|
33
|
+
response = "\0RES" + [Gearman::Protocol::COMMANDS_NUMERIC[:work_complete], data.size].pack("NN") + [handle, data].join("\0")
|
34
|
+
assert_equal [:work_complete, handle, data], Gearman::Protocol.decode_response(response).first
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_decodes_work_exception
|
38
|
+
data = "{native perl exception object}"
|
39
|
+
response = "\0RES" + [Gearman::Protocol::COMMANDS_NUMERIC[:work_exception], data.size].pack("NN") + [handle, data].join("\0")
|
40
|
+
assert_equal [:work_exception, handle, data], Gearman::Protocol.decode_response(response).first
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_decodes_work_warning
|
44
|
+
data = "I warn you, dude"
|
45
|
+
response = "\0RES" + [Gearman::Protocol::COMMANDS_NUMERIC[:work_warning], data.size].pack("NN") + [handle, data].join("\0")
|
46
|
+
assert_equal [:work_warning, handle, data], Gearman::Protocol.decode_response(response).first
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_decodes_work_data
|
50
|
+
data = "foo"
|
51
|
+
response = "\0RES" + [Gearman::Protocol::COMMANDS_NUMERIC[:work_data], data.size].pack("NN") + [handle, data].join("\0")
|
52
|
+
assert_equal [:work_data, handle, data], Gearman::Protocol.decode_response(response).first
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_decodes_error
|
56
|
+
data = "error"
|
57
|
+
response = "\0RES" + [Gearman::Protocol::COMMANDS_NUMERIC[:error], data.size].pack("NN") + [handle, data].join("\0")
|
58
|
+
assert_equal [:error, handle, data], Gearman::Protocol.decode_response(response).first
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_decodes_job_assign
|
62
|
+
function = "foo_function"
|
63
|
+
arguments = "arguments"
|
64
|
+
|
65
|
+
payload = [handle, function, arguments].join("\0")
|
66
|
+
response = "\0RES" + [Gearman::Protocol::COMMANDS_NUMERIC[:job_assign], payload.size].pack("NN") + payload
|
67
|
+
assert_equal [:job_assign, handle, function, arguments], Gearman::Protocol.decode_response(response).first
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_decodes_job_assign_uniq
|
71
|
+
function = "foo_function"
|
72
|
+
arguments = "arguments"
|
73
|
+
unique_id = "123-657"
|
74
|
+
|
75
|
+
payload = [handle, function, unique_id, arguments].join("\0")
|
76
|
+
response = "\0RES" + [Gearman::Protocol::COMMANDS_NUMERIC[:job_assign_uniq], payload.size].pack("NN") + payload
|
77
|
+
assert_equal [:job_assign_uniq, handle, function, arguments, unique_id], Gearman::Protocol.decode_response(response).first
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_decodes_work_fail
|
81
|
+
response = "\0RES" + [Gearman::Protocol::COMMANDS_NUMERIC[:work_fail], 0].pack("NN") + handle
|
82
|
+
assert_equal [:work_fail, handle], Gearman::Protocol.decode_response(response).first
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_decodes_job_created
|
86
|
+
response = "\0RES" + [Gearman::Protocol::COMMANDS_NUMERIC[:job_created], 0].pack("NN") + handle
|
87
|
+
assert_equal [:job_created, handle], Gearman::Protocol.decode_response(response).first
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_decodes_no_job
|
91
|
+
response = "\0RES" + [Gearman::Protocol::COMMANDS_NUMERIC[:no_job], 0].pack("NN") + handle
|
92
|
+
assert_equal [:no_job, handle], Gearman::Protocol.decode_response(response).first
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_decodes_noop
|
96
|
+
response = "\0RES" + [Gearman::Protocol::COMMANDS_NUMERIC[:noop], 0].pack("NN") + handle
|
97
|
+
assert_equal [:noop, handle], Gearman::Protocol.decode_response(response).first
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_decodes_work_status
|
101
|
+
numerator = "1"
|
102
|
+
denominator = "5"
|
103
|
+
|
104
|
+
payload = [handle, numerator, denominator].join("\0")
|
105
|
+
response = "\0RES" + [Gearman::Protocol::COMMANDS_NUMERIC[:work_status], payload.size].pack("NN") + payload
|
106
|
+
|
107
|
+
assert_equal [:work_status, handle, numerator, denominator], Gearman::Protocol.decode_response(response).first
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_decodes_status_res
|
111
|
+
known = "1"
|
112
|
+
running = "0"
|
113
|
+
numerator = "1"
|
114
|
+
denominator = "4"
|
115
|
+
|
116
|
+
payload = [handle, known, running, numerator, denominator].join("\0")
|
117
|
+
response = "\0RES" + [Gearman::Protocol::COMMANDS_NUMERIC[:status_res], payload.size].pack("NN") + payload
|
118
|
+
|
119
|
+
assert_equal [:status_res, handle, known, running, numerator, denominator], Gearman::Protocol.decode_response(response).first
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_raises_on_invalid_command
|
123
|
+
response = "\0RES" + [6969, 0].pack("NN")
|
124
|
+
assert_raises(Gearman::ProtocolError) { Gearman::Protocol.decode_response(response) }
|
125
|
+
assert_raises(Gearman::ProtocolError) { Gearman::Protocol.response_packet(*[6969, handle, ''])}
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
def handle
|
130
|
+
"H:wrk.acme:1"
|
131
|
+
end
|
132
|
+
end
|