homeq 1.1.4
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/CHANGELOG +103 -0
- data/COPYING +348 -0
- data/README.rdoc +64 -0
- data/Rakefile +131 -0
- data/bin/hq +6 -0
- data/config/boot.rb +224 -0
- data/config/databases/frontbase.yml +28 -0
- data/config/databases/mysql.yml +54 -0
- data/config/databases/oracle.yml +39 -0
- data/config/databases/postgresql.yml +48 -0
- data/config/databases/sqlite2.yml +16 -0
- data/config/databases/sqlite3.yml +19 -0
- data/config/environment.rb +20 -0
- data/config/environments/development.cfg +35 -0
- data/config/environments/production.cfg +35 -0
- data/config/environments/test.cfg +35 -0
- data/config/generators/job/templates/job.rb.erb +20 -0
- data/config/generators/message/templates/messages/MESSAGE.proto.erb +12 -0
- data/config/generators/model/templates/models/MODEL.rb.erb +3 -0
- data/config/generators/service/templates/services/SERVICE.rb.erb +43 -0
- data/config/homeq.cfg +35 -0
- data/extras/consumer.rb +85 -0
- data/extras/homeq.cfg +49 -0
- data/extras/hqd.rb +33 -0
- data/extras/producer.rb +79 -0
- data/extras/simple_consumer.rb +53 -0
- data/lib/homeq/base/base.rb +44 -0
- data/lib/homeq/base/commando.rb +81 -0
- data/lib/homeq/base/config.rb +99 -0
- data/lib/homeq/base/exception.rb +48 -0
- data/lib/homeq/base/histogram.rb +141 -0
- data/lib/homeq/base/logger.rb +185 -0
- data/lib/homeq/base/ohash.rb +297 -0
- data/lib/homeq/base/options.rb +171 -0
- data/lib/homeq/base/poolable.rb +100 -0
- data/lib/homeq/base/system.rb +446 -0
- data/lib/homeq/cli.rb +35 -0
- data/lib/homeq/cp/commands.rb +71 -0
- data/lib/homeq/cp/connection.rb +97 -0
- data/lib/homeq/cp/cp.rb +30 -0
- data/lib/homeq/cp/server.rb +105 -0
- data/lib/homeq/sobs/client.rb +119 -0
- data/lib/homeq/sobs/connection.rb +635 -0
- data/lib/homeq/sobs/foreman.rb +237 -0
- data/lib/homeq/sobs/job.rb +66 -0
- data/lib/homeq/sobs/message.rb +49 -0
- data/lib/homeq/sobs/queue.rb +224 -0
- data/lib/homeq/sobs/sender.rb +150 -0
- data/lib/homeq/sobs/server.rb +654 -0
- data/lib/homeq/sobs/sobs.rb +45 -0
- data/lib/homeq/sobs/topology.rb +111 -0
- data/lib/homeq.rb +106 -0
- data/lib/tasks/Rakefile +49 -0
- data/lib/tasks/database.rake +387 -0
- data/lib/tasks/gem.rake +9 -0
- data/lib/tasks/generate.rake +192 -0
- data/lib/tasks/hq.rake +171 -0
- data/lib/tasks/testing.rake +95 -0
- data/lib/tasks/utility.rb +17 -0
- data/script/console.rb +45 -0
- data/script/generate +7 -0
- data/test/unittest.rb +51 -0
- metadata +222 -0
@@ -0,0 +1,237 @@
|
|
1
|
+
#############################################################################
|
2
|
+
#
|
3
|
+
# $Id: foreman.rb 40 2008-10-23 14:20:06Z colin $
|
4
|
+
#
|
5
|
+
# Author:: Colin Steele (colin@colinsteele.org)
|
6
|
+
# Homepage::
|
7
|
+
#
|
8
|
+
# TODO: info
|
9
|
+
#
|
10
|
+
#----------------------------------------------------------------------------
|
11
|
+
#
|
12
|
+
# Copyright (C) 2008 by Colin Steele. All Rights Reserved.
|
13
|
+
# colin@colinsteele.org
|
14
|
+
#
|
15
|
+
# This program is free software; you can redistribute it and/or modify
|
16
|
+
# it under the terms of either: 1) the GNU General Public License
|
17
|
+
# as published by the Free Software Foundation; either version 2 of the
|
18
|
+
# License, or (at your option) any later version; or 2) Ruby's License.
|
19
|
+
#
|
20
|
+
# See the file COPYING for complete licensing information.
|
21
|
+
#
|
22
|
+
#---------------------------------------------------------------------------
|
23
|
+
#
|
24
|
+
#
|
25
|
+
#############################################################################
|
26
|
+
|
27
|
+
module HomeQ
|
28
|
+
|
29
|
+
module SOBS
|
30
|
+
|
31
|
+
######################################################################
|
32
|
+
# Job Manager
|
33
|
+
######################################################################
|
34
|
+
|
35
|
+
class Foreman
|
36
|
+
|
37
|
+
MAX_JOBS_TO_DOLE_OUT_PER_TICK = 100
|
38
|
+
|
39
|
+
include Base::Logging
|
40
|
+
|
41
|
+
attr :server, true
|
42
|
+
attr :jobs, true
|
43
|
+
|
44
|
+
def initialize(server)
|
45
|
+
@serial_number = 0
|
46
|
+
@server = server
|
47
|
+
@jobs = {} # Each element is a [job, job_state, time] tuple
|
48
|
+
@states = {
|
49
|
+
:start => HomeQ::OHash.new,
|
50
|
+
:ready => HomeQ::OHash.new,
|
51
|
+
:deleted => HomeQ::OHash.new,
|
52
|
+
:delayed => HomeQ::OHash.new,
|
53
|
+
:reserved => HomeQ::OHash.new,
|
54
|
+
:buried => HomeQ::OHash.new,
|
55
|
+
}
|
56
|
+
@jobs_created = 0
|
57
|
+
@jobs_deleted = 0
|
58
|
+
@jobs_doled_out = 0
|
59
|
+
@histo = HomeQ::Histogram.new(0,10,0.5)
|
60
|
+
dole_out_jobs
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_job(message, connection)
|
64
|
+
@jobs_created += 1
|
65
|
+
j = ServerJob.new(message, connection)
|
66
|
+
j.add_observer(self)
|
67
|
+
j.run
|
68
|
+
end
|
69
|
+
|
70
|
+
def update(job, state)
|
71
|
+
track_job_by_state(job, state) if job.job_id
|
72
|
+
case state
|
73
|
+
when :start
|
74
|
+
job.job_id = unique_job_id
|
75
|
+
@jobs[job.job_id] = [job, state, Time.now]
|
76
|
+
# call now b/c we now have a job_id
|
77
|
+
track_job_by_state(job, state)
|
78
|
+
job.queue.inserted(job.job_id, job.message.args[3])
|
79
|
+
when :deleted
|
80
|
+
@histo << (Time.now - @jobs[job.job_id][2])
|
81
|
+
@jobs.delete(job.job_id)
|
82
|
+
remove_job_from_all_states(job)
|
83
|
+
job.delete_observer(self)
|
84
|
+
job.recycle
|
85
|
+
@jobs_deleted += 1
|
86
|
+
when :ready
|
87
|
+
dole_out_jobs
|
88
|
+
when :delayed
|
89
|
+
when :reserved
|
90
|
+
when :buried
|
91
|
+
else
|
92
|
+
Base::System.instance.die("Unknown job state #{state}")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def release_job(conn, job_id, priority, delay)
|
97
|
+
j = job_id_in_state?(job_id, :reserved)
|
98
|
+
if !j
|
99
|
+
conn.not_found(job_id)
|
100
|
+
return
|
101
|
+
end
|
102
|
+
if delay.to_i > 0
|
103
|
+
j.release_with_delay(priority.to_i, delay.to_i)
|
104
|
+
else
|
105
|
+
j.release
|
106
|
+
end
|
107
|
+
conn.released(job_id)
|
108
|
+
end
|
109
|
+
|
110
|
+
def delete_job(conn, job_id)
|
111
|
+
[:buried, :reserved].each { |state|
|
112
|
+
j = job_id_in_state?(job_id, state)
|
113
|
+
if j
|
114
|
+
j.delete(conn)
|
115
|
+
return
|
116
|
+
end
|
117
|
+
}
|
118
|
+
conn.not_found(job_id)
|
119
|
+
end
|
120
|
+
|
121
|
+
def bury_job(conn, job_id)
|
122
|
+
j = job_id_in_state?(job_id, :reserved)
|
123
|
+
if j
|
124
|
+
j.bury(conn)
|
125
|
+
return
|
126
|
+
end
|
127
|
+
conn.not_found(job_id)
|
128
|
+
end
|
129
|
+
|
130
|
+
def kick(conn, max_jobs)
|
131
|
+
kicked = []
|
132
|
+
0.upto(max_jobs.to_i - 1) { |i|
|
133
|
+
kicked << @states[:buried].shift
|
134
|
+
}
|
135
|
+
conn.kicked(kicked.length)
|
136
|
+
kicked.each { |jid,j|
|
137
|
+
@jobs[jid][0].kick
|
138
|
+
}
|
139
|
+
end
|
140
|
+
|
141
|
+
def dole_out_jobs
|
142
|
+
# To give the reactor (EM) loop a chance to actually run, we
|
143
|
+
# only send out a few jobs at a time.
|
144
|
+
1.upto(MAX_JOBS_TO_DOLE_OUT_PER_TICK) do
|
145
|
+
return unless ready_jobs?
|
146
|
+
c = find_waiting_connection
|
147
|
+
return unless c
|
148
|
+
j = get_next_ready_job
|
149
|
+
@jobs_doled_out += 1
|
150
|
+
j.reserve(c)
|
151
|
+
end
|
152
|
+
EventMachine::next_tick {
|
153
|
+
dole_out_jobs
|
154
|
+
}
|
155
|
+
end
|
156
|
+
|
157
|
+
def to_s
|
158
|
+
str = "#{self.class} "
|
159
|
+
str << "Pool size: #{ServerJob.pool.size}\n"
|
160
|
+
str << "created: #{@jobs_created} deleted: #{@jobs_deleted} "
|
161
|
+
str << "doled out: #{@jobs_doled_out}\n"
|
162
|
+
@states.each { |state, oh|
|
163
|
+
str << "#{state.to_s.capitalize} jobs: #{oh.length}\n" if oh.length>0
|
164
|
+
}
|
165
|
+
str << @histo.report
|
166
|
+
str
|
167
|
+
end
|
168
|
+
|
169
|
+
protected
|
170
|
+
|
171
|
+
def ready_jobs?
|
172
|
+
@states[:ready].length > 0
|
173
|
+
end
|
174
|
+
|
175
|
+
def get_next_ready_job
|
176
|
+
if @states[:ready] && (@states[:ready].length > 0)
|
177
|
+
jid, j = @states[:ready].shift # pull it from the front of the dict
|
178
|
+
if j != @jobs[jid][0]
|
179
|
+
Base::System.instance.die("Foreman corrupted, bye.")
|
180
|
+
end
|
181
|
+
return j
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def job_id_in_state?(jid, state)
|
186
|
+
jid = jid.to_sym
|
187
|
+
return false unless @jobs[jid][0]
|
188
|
+
if @states[state].length > 0
|
189
|
+
if @states[state].has_key?(jid)
|
190
|
+
return @jobs[jid][0]
|
191
|
+
end
|
192
|
+
end
|
193
|
+
false
|
194
|
+
end
|
195
|
+
|
196
|
+
def find_waiting_connection
|
197
|
+
waiters = @server.connections.find_all { |c|
|
198
|
+
c.server_state.state == :waiting_for_job
|
199
|
+
}
|
200
|
+
if waiters.any?
|
201
|
+
waiters[rand(waiters.length)]
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def track_job_by_state(job, new_state)
|
206
|
+
remove_job_from_old_state(job)
|
207
|
+
@jobs[job.job_id][1] = new_state
|
208
|
+
@states[new_state].push(job.job_id, job)
|
209
|
+
end
|
210
|
+
|
211
|
+
def remove_job_from_old_state(job)
|
212
|
+
old_state = @jobs[job.job_id][1]
|
213
|
+
@states[old_state].delete(job.job_id)
|
214
|
+
end
|
215
|
+
|
216
|
+
def remove_job_from_all_states(job)
|
217
|
+
@states.each { |state_name,dict|
|
218
|
+
dict.delete(job.job_id) if dict.has_key?(job.job_id)
|
219
|
+
}
|
220
|
+
end
|
221
|
+
|
222
|
+
# Get a job id unique to this foreman
|
223
|
+
def unique_job_id
|
224
|
+
loop do
|
225
|
+
# This was the old way
|
226
|
+
# jid = UUID.timestamp_create.to_s.to_sym
|
227
|
+
jid = "#{@serial_number}".to_sym
|
228
|
+
@serial_number += 1
|
229
|
+
return jid if !@jobs.include?(jid)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
end # Foreman
|
234
|
+
|
235
|
+
end # SOBS
|
236
|
+
|
237
|
+
end # HomeQ
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#############################################################################
|
2
|
+
#
|
3
|
+
# $Id: job.rb 40 2008-10-23 14:20:06Z colin $
|
4
|
+
#
|
5
|
+
# Author:: Colin Steele (colin@colinsteele.org)
|
6
|
+
# Homepage::
|
7
|
+
#
|
8
|
+
# TODO: info
|
9
|
+
#
|
10
|
+
#----------------------------------------------------------------------------
|
11
|
+
#
|
12
|
+
# Copyright (C) 2008 by Colin Steele. All Rights Reserved.
|
13
|
+
# colin@colinsteele.org
|
14
|
+
#
|
15
|
+
# This program is free software; you can redistribute it and/or modify
|
16
|
+
# it under the terms of either: 1) the GNU General Public License
|
17
|
+
# as published by the Free Software Foundation; either version 2 of the
|
18
|
+
# License, or (at your option) any later version; or 2) Ruby's License.
|
19
|
+
#
|
20
|
+
# See the file COPYING for complete licensing information.
|
21
|
+
#
|
22
|
+
#---------------------------------------------------------------------------
|
23
|
+
#
|
24
|
+
#
|
25
|
+
#############################################################################
|
26
|
+
|
27
|
+
module HomeQ
|
28
|
+
|
29
|
+
module SOBS
|
30
|
+
|
31
|
+
class Job
|
32
|
+
|
33
|
+
include Base::Options
|
34
|
+
include Base::Configuration
|
35
|
+
include Base::Logging
|
36
|
+
|
37
|
+
attr :message, true
|
38
|
+
attr :queue, true
|
39
|
+
attr :job_id, true
|
40
|
+
|
41
|
+
def initialize(message, queue)
|
42
|
+
@queue = queue
|
43
|
+
@message = message
|
44
|
+
@job_id = @message.job_id
|
45
|
+
end
|
46
|
+
|
47
|
+
def payload
|
48
|
+
@message.payload
|
49
|
+
end
|
50
|
+
|
51
|
+
# Override here, and call super
|
52
|
+
def run
|
53
|
+
complete
|
54
|
+
end
|
55
|
+
|
56
|
+
protected
|
57
|
+
|
58
|
+
def complete
|
59
|
+
@queue.release_job(self) if @queue
|
60
|
+
end
|
61
|
+
|
62
|
+
end # Job
|
63
|
+
|
64
|
+
end # SOBS
|
65
|
+
|
66
|
+
end # HomeQ
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#############################################################################
|
2
|
+
#
|
3
|
+
# $Id: message.rb 40 2008-10-23 14:20:06Z colin $
|
4
|
+
#
|
5
|
+
# Author:: Colin Steele (colin@colinsteele.org)
|
6
|
+
# Homepage::
|
7
|
+
#
|
8
|
+
# TODO: info
|
9
|
+
#
|
10
|
+
#----------------------------------------------------------------------------
|
11
|
+
#
|
12
|
+
# Copyright (C) 2008 by Colin Steele. All Rights Reserved.
|
13
|
+
# colin@colinsteele.org
|
14
|
+
#
|
15
|
+
# This program is free software; you can redistribute it and/or modify
|
16
|
+
# it under the terms of either: 1) the GNU General Public License
|
17
|
+
# as published by the Free Software Foundation; either version 2 of the
|
18
|
+
# License, or (at your option) any later version; or 2) Ruby's License.
|
19
|
+
#
|
20
|
+
# See the file COPYING for complete licensing information.
|
21
|
+
#
|
22
|
+
#---------------------------------------------------------------------------
|
23
|
+
#
|
24
|
+
#
|
25
|
+
#############################################################################
|
26
|
+
|
27
|
+
module HomeQ
|
28
|
+
|
29
|
+
module SOBS
|
30
|
+
|
31
|
+
class Message
|
32
|
+
|
33
|
+
attr :type, true
|
34
|
+
attr :job_id, true
|
35
|
+
attr :payload, true
|
36
|
+
attr :args, true
|
37
|
+
|
38
|
+
def initialize(message_type=nil, job_id=nil, payload=nil, args=nil)
|
39
|
+
@type = message_type
|
40
|
+
@job_id = job_id
|
41
|
+
@payload = payload
|
42
|
+
@args = args
|
43
|
+
end
|
44
|
+
|
45
|
+
end # Message
|
46
|
+
|
47
|
+
end # SOBS
|
48
|
+
|
49
|
+
end # HomeQ
|
@@ -0,0 +1,224 @@
|
|
1
|
+
#############################################################################
|
2
|
+
#
|
3
|
+
# $Id: queue.rb 48 2008-11-19 05:11:59Z colin $
|
4
|
+
#
|
5
|
+
# Author:: Colin Steele (colin@colinsteele.org)
|
6
|
+
# Homepage::
|
7
|
+
#
|
8
|
+
# TODO: info
|
9
|
+
#
|
10
|
+
#----------------------------------------------------------------------------
|
11
|
+
#
|
12
|
+
# Copyright (C) 2008 by Colin Steele. All Rights Reserved.
|
13
|
+
# colin@colinsteele.org
|
14
|
+
#
|
15
|
+
# This program is free software; you can redistribute it and/or modify
|
16
|
+
# it under the terms of either: 1) the GNU General Public License
|
17
|
+
# as published by the Free Software Foundation; either version 2 of the
|
18
|
+
# License, or (at your option) any later version; or 2) Ruby's License.
|
19
|
+
#
|
20
|
+
# See the file COPYING for complete licensing information.
|
21
|
+
#
|
22
|
+
#---------------------------------------------------------------------------
|
23
|
+
#
|
24
|
+
#
|
25
|
+
#############################################################################
|
26
|
+
|
27
|
+
require 'observer'
|
28
|
+
|
29
|
+
module HomeQ
|
30
|
+
|
31
|
+
module SOBS
|
32
|
+
|
33
|
+
class Queue
|
34
|
+
|
35
|
+
include Observable
|
36
|
+
include Base::Logging
|
37
|
+
include Base::Configuration
|
38
|
+
include HomeQ
|
39
|
+
|
40
|
+
READ_ONLY = 'r'
|
41
|
+
WRITE_ONLY = 'w'
|
42
|
+
READ_WRITE = 'w+'
|
43
|
+
MODES = [READ_ONLY, WRITE_ONLY, READ_WRITE]
|
44
|
+
|
45
|
+
attr :queue_name, true
|
46
|
+
attr :host, true
|
47
|
+
attr :port, true
|
48
|
+
attr :mode, true
|
49
|
+
attr :args, true
|
50
|
+
attr :handler, true
|
51
|
+
|
52
|
+
# Make our config available
|
53
|
+
module HomeQ::Base::Commando::InstanceMethods
|
54
|
+
config_accessor :queue_retry
|
55
|
+
document_command "queue_retry [int]", "Get/set reconnect interval"
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.[](queue_name)
|
59
|
+
sys.queues.find { |q|
|
60
|
+
q.queue_name == queue_name
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.send(queue_name, data, app_data=nil, &block)
|
65
|
+
dest = Queue[queue_name]
|
66
|
+
unless dest
|
67
|
+
raise HomeQ::Base::UnknownQueue.new("Can't find queue #{queue_name}")
|
68
|
+
end
|
69
|
+
raise HomeQ::Base::ReadOnlyQueue unless dest.writeable?
|
70
|
+
dest.send(data, app_data, block)
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.create_queues_from_topology(queuename)
|
74
|
+
config = HomeQ::Base::Configuration::Configuration.instance
|
75
|
+
q, host, port, hostname = config.topology[queuename]
|
76
|
+
config.topology.connections(q).each { |peer,mode,threshold|
|
77
|
+
raise "No config for queue '#{peer}'." unless config.topology[peer]
|
78
|
+
q, host, port = config.topology[peer]
|
79
|
+
queue = HomeQ::SOBS::Queue.new(q, host, port, mode, threshold)
|
80
|
+
Base::System.instance.queues << queue
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
def initialize(*args)
|
85
|
+
@queue_name, @host, @port, @mode, @threshold, @args = args
|
86
|
+
raise "Nil queue_name, probably a config error" unless @queue_name
|
87
|
+
|
88
|
+
@conn = nil
|
89
|
+
@retry_timer = config.queue_retry || 5
|
90
|
+
@acks = {}
|
91
|
+
|
92
|
+
# stats
|
93
|
+
|
94
|
+
@concurrent_outstanding_jobs = 0
|
95
|
+
@concurrent_outstanding_jobs_highwater = 0
|
96
|
+
@jobs_received = 0
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
def start
|
101
|
+
logger.info {
|
102
|
+
"Initiating connection to queue '#{@queue_name}' " +
|
103
|
+
"at #{@host}:#{@port}, mode '#{@mode}', " +
|
104
|
+
"handler #{(@handler || Job)}."
|
105
|
+
}
|
106
|
+
Client.connect(host, port, config.queue_retry || 5, nil, self)
|
107
|
+
end
|
108
|
+
|
109
|
+
def closed
|
110
|
+
if @conn
|
111
|
+
logger.info {
|
112
|
+
"Disconnected from queue '#{queue_name}' " +
|
113
|
+
"on #{@conn.remote_endpoint}."
|
114
|
+
}
|
115
|
+
@started_at = nil
|
116
|
+
@conn = nil
|
117
|
+
end
|
118
|
+
broadcast_change
|
119
|
+
end
|
120
|
+
|
121
|
+
def opened(conn)
|
122
|
+
@conn = conn
|
123
|
+
@conn.refuse_send_threshold = @threshold if @threshold
|
124
|
+
@started_at = Time.now
|
125
|
+
logger.info {
|
126
|
+
"Connected to '#{queue_name}' on #{conn.remote_endpoint}."
|
127
|
+
}
|
128
|
+
broadcast_change
|
129
|
+
end
|
130
|
+
|
131
|
+
def stop
|
132
|
+
@conn.close_connection_after_writing if @conn
|
133
|
+
end
|
134
|
+
|
135
|
+
def release_job(job)
|
136
|
+
@conn.delete(job.job_id)
|
137
|
+
@concurrent_outstanding_jobs -= 1
|
138
|
+
end
|
139
|
+
|
140
|
+
def ack(message)
|
141
|
+
app_data = message.args[1]
|
142
|
+
if @acks[app_data.to_sym]
|
143
|
+
@acks[app_data.to_sym].call(app_data)
|
144
|
+
@acks.delete(app_data.to_sym)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def deleted(message)
|
149
|
+
end
|
150
|
+
|
151
|
+
def create_job(message)
|
152
|
+
@jobs_received += 1
|
153
|
+
@concurrent_outstanding_jobs += 1
|
154
|
+
if @concurrent_outstanding_jobs > 100
|
155
|
+
logger.warn {
|
156
|
+
"Outstanding jobs: #{@concurrent_outstanding_jobs}"
|
157
|
+
}
|
158
|
+
end
|
159
|
+
set_jobs_highwater
|
160
|
+
j = (@handler || Job).new(message, self)
|
161
|
+
j.run if j.respond_to?(:run)
|
162
|
+
end
|
163
|
+
|
164
|
+
def set_jobs_highwater
|
165
|
+
@concurrent_outstanding_jobs_highwater = [
|
166
|
+
@concurrent_outstanding_jobs_highwater,
|
167
|
+
@concurrent_outstanding_jobs
|
168
|
+
].max
|
169
|
+
end
|
170
|
+
|
171
|
+
def send(data, app_data=nil, proc=nil)
|
172
|
+
return if !@conn || @conn.state.state != :open
|
173
|
+
app_data ||= generate_app_data
|
174
|
+
@acks[app_data.to_s.to_sym] = proc if proc
|
175
|
+
@conn.put(:body=>data, :app_data=>app_data)
|
176
|
+
end
|
177
|
+
|
178
|
+
def writeable?
|
179
|
+
mode != READ_ONLY
|
180
|
+
end
|
181
|
+
|
182
|
+
def readable?
|
183
|
+
mode != WRITE_ONLY
|
184
|
+
end
|
185
|
+
|
186
|
+
def connected?
|
187
|
+
@conn ? true : false
|
188
|
+
end
|
189
|
+
|
190
|
+
protected
|
191
|
+
|
192
|
+
# A unique id
|
193
|
+
def generate_app_data
|
194
|
+
UUID.timestamp_create.to_sym
|
195
|
+
end
|
196
|
+
|
197
|
+
# Tell folks something.
|
198
|
+
def broadcast_change
|
199
|
+
changed
|
200
|
+
notify_observers(self)
|
201
|
+
end
|
202
|
+
|
203
|
+
# String representation of queue
|
204
|
+
def to_s
|
205
|
+
str = ''
|
206
|
+
str << "Queuename: #{@queue_name}"
|
207
|
+
str << " on #{@host}:#{@port}" if @host || @port
|
208
|
+
str << " mode #{@mode}"
|
209
|
+
str << " handler #{(@handler || Job)}"
|
210
|
+
str << "\n"
|
211
|
+
str << "Jobs rcvd: #{@jobs_received}, "
|
212
|
+
str << " highwater: #{@concurrent_outstanding_jobs_highwater}"
|
213
|
+
str << "\n"
|
214
|
+
if connected?
|
215
|
+
str << @conn.to_s
|
216
|
+
end
|
217
|
+
str
|
218
|
+
end
|
219
|
+
|
220
|
+
end # Queue
|
221
|
+
|
222
|
+
end # SOBS
|
223
|
+
|
224
|
+
end # HomeQ
|