simple_worker 2.0.0.beta.11 → 2.0.0.beta.15
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/README.markdown +9 -3
- data/lib/simple_worker/api.rb +67 -11
- data/lib/simple_worker/base.rb +19 -14
- data/lib/simple_worker/service.rb +58 -60
- metadata +13 -2
data/README.markdown
CHANGED
@@ -80,6 +80,14 @@ Let's say someone does something in your app and you want to send an email about
|
|
80
80
|
|
81
81
|
This will send it off to the SimpleWorker cloud.
|
82
82
|
|
83
|
+
To queue worker without uploading you could try to do following:
|
84
|
+
|
85
|
+
data[:attr_encoded] = Base64.encode64({'@to'=>'example@email.com'}.to_json)
|
86
|
+
data[:sw_config] = SimpleWorker.config.get_atts_to_send
|
87
|
+
SimpleWorker.service.queue('EmailWorker', data)
|
88
|
+
|
89
|
+
|
90
|
+
|
83
91
|
Setting Priority
|
84
92
|
----------------------------------------------
|
85
93
|
|
@@ -261,9 +269,7 @@ You could easily merge mailers you're using in your application.
|
|
261
269
|
#or
|
262
270
|
merge_mailer 'mailer_file', {:path_to_templates=>"templates_path"}#if you're using mailer outside of rails with custom templates path
|
263
271
|
|
264
|
-
|
265
|
-
|
266
|
-
Configuring a Mailer Connection
|
272
|
+
### Configuring a Mailer Connection
|
267
273
|
|
268
274
|
If you are using Rails 3,your action_mailer connection would be configured automatically from your config
|
269
275
|
|
data/lib/simple_worker/api.rb
CHANGED
@@ -1,6 +1,19 @@
|
|
1
1
|
require 'rest_client'
|
2
|
+
require 'patron'
|
2
3
|
|
3
4
|
module SimpleWorker
|
5
|
+
|
6
|
+
class RequestError < StandardError
|
7
|
+
def initialize(msg, options={})
|
8
|
+
super(msg)
|
9
|
+
@options = options
|
10
|
+
end
|
11
|
+
|
12
|
+
def status
|
13
|
+
@options[:status]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
4
17
|
module Api
|
5
18
|
|
6
19
|
module Signatures
|
@@ -30,7 +43,7 @@ module SimpleWorker
|
|
30
43
|
# host: endpoint url for service
|
31
44
|
class Client
|
32
45
|
|
33
|
-
attr_accessor :host, :port, :token, :version, :config
|
46
|
+
attr_accessor :scheme, :host, :port, :token, :version, :config
|
34
47
|
|
35
48
|
def initialize(host, token, options={})
|
36
49
|
@config = options[:config]
|
@@ -41,10 +54,25 @@ module SimpleWorker
|
|
41
54
|
@version = options[:version]
|
42
55
|
@logger = options[:logger]
|
43
56
|
|
57
|
+
@base_url = "#{@scheme}://#{@host}:#{@port}/#{@version}"
|
58
|
+
|
59
|
+
sess = Patron::Session.new
|
60
|
+
sess.timeout = 10
|
61
|
+
sess.base_url = @base_url
|
62
|
+
sess.headers['User-Agent'] = 'IronMQ Ruby Client'
|
63
|
+
#sess.enable_debug "/tmp/patron.debug"
|
64
|
+
@http_sess = sess
|
65
|
+
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
def base_url
|
71
|
+
@base_url
|
44
72
|
end
|
45
73
|
|
46
74
|
def url(command_path)
|
47
|
-
url = "#{
|
75
|
+
url = "#{base_url}/#{command_path}"
|
48
76
|
# @logger.debug "url: " + url.to_s
|
49
77
|
url
|
50
78
|
end
|
@@ -59,15 +87,32 @@ module SimpleWorker
|
|
59
87
|
raise exception
|
60
88
|
end
|
61
89
|
|
90
|
+
def check_response(response, options={})
|
91
|
+
status = response.status
|
92
|
+
body = response.body
|
93
|
+
res = nil
|
94
|
+
unless options[:parse] == false
|
95
|
+
res = JSON.parse(body)
|
96
|
+
end
|
97
|
+
if status < 400
|
98
|
+
|
99
|
+
else
|
100
|
+
raise SimpleWorker::RequestError.new((res ? "#{status}: #{res["msg"]}" : "#{status} Error! parse=false so no msg"), :status=>status)
|
101
|
+
end
|
102
|
+
res || body
|
103
|
+
end
|
104
|
+
|
62
105
|
def get(method, params={}, options={})
|
63
106
|
full_url = url(method)
|
64
107
|
all_params = add_params(method, params)
|
65
|
-
|
66
108
|
url_plus_params = append_params(full_url, all_params)
|
67
109
|
@logger.debug 'get url=' + url_plus_params
|
68
|
-
|
69
|
-
|
70
|
-
|
110
|
+
response = @http_sess.request(:get, url_plus_params,
|
111
|
+
{},
|
112
|
+
{})
|
113
|
+
check_response(response, options)
|
114
|
+
body = response.body
|
115
|
+
parse_response(body, options)
|
71
116
|
|
72
117
|
end
|
73
118
|
|
@@ -79,9 +124,9 @@ module SimpleWorker
|
|
79
124
|
@logger.debug "data = " + data
|
80
125
|
@logger.debug "params = " + params.inspect
|
81
126
|
@logger.debug "options = " + options.inspect
|
82
|
-
|
83
|
-
|
84
|
-
rescue
|
127
|
+
# todo: replace with patron
|
128
|
+
parse_response(RestClient.post(append_params(url(method), add_params(method, params)), {:data => data, :file => file}, :content_type => 'application/json'), options)
|
129
|
+
rescue Exception => ex
|
85
130
|
process_ex(ex)
|
86
131
|
end
|
87
132
|
end
|
@@ -94,8 +139,17 @@ module SimpleWorker
|
|
94
139
|
begin
|
95
140
|
url = url(method) + "?oauth=" + token
|
96
141
|
@logger.debug 'post url=' + url
|
97
|
-
|
98
|
-
|
142
|
+
json = add_params(method, params).to_json
|
143
|
+
@logger.debug 'body=' + json
|
144
|
+
response = @http_sess.post(url, json, {"Content-Type" => 'application/json'})
|
145
|
+
check_response(response)
|
146
|
+
@logger.debug 'response: ' + response.inspect
|
147
|
+
body = response.body
|
148
|
+
parse_response(body, options)
|
149
|
+
rescue SimpleWorker::RequestError => ex
|
150
|
+
# let it throw, came from check_response
|
151
|
+
raise ex
|
152
|
+
rescue Exception => ex
|
99
153
|
@logger.warn("Exception in post! #{ex.message}")
|
100
154
|
@logger.warn(ex.backtrace.join("\n"))
|
101
155
|
process_ex(ex)
|
@@ -105,6 +159,7 @@ module SimpleWorker
|
|
105
159
|
|
106
160
|
def put(method, body, options={})
|
107
161
|
begin
|
162
|
+
# todo: replace with patron
|
108
163
|
parse_response RestClient.put(url(method), add_params(method, body).to_json, headers), options
|
109
164
|
rescue RestClient::Exception => ex
|
110
165
|
process_ex(ex)
|
@@ -113,6 +168,7 @@ module SimpleWorker
|
|
113
168
|
|
114
169
|
def delete(method, params={}, options={})
|
115
170
|
begin
|
171
|
+
# todo: replace with patron
|
116
172
|
parse_response RestClient.delete(append_params(url(method), add_params(method, params))), options
|
117
173
|
rescue RestClient::Exception => ex
|
118
174
|
process_ex(ex)
|
data/lib/simple_worker/base.rb
CHANGED
@@ -41,11 +41,16 @@ module SimpleWorker
|
|
41
41
|
def merge_gem(gem_name, options={})
|
42
42
|
gem_info = SimpleWorker::MergeHelper.create_gem_info(gem_name, options)
|
43
43
|
@merged_gems[gem_name.to_s] = gem_info
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
44
|
+
reqs = gem_info[:require].is_a?(Array) ? gem_info[:require] : [gem_info[:require]]
|
45
|
+
reqs.each do |r|
|
46
|
+
r2 = "#{gem_info[:path]}/lib/#{r}"
|
47
|
+
begin
|
48
|
+
puts 'requiring ' + r2
|
49
|
+
require r2
|
50
|
+
rescue LoadError=>ex
|
51
|
+
SimpleWorker.logger.error "Error requiring gem #{r}: #{ex.message}"
|
52
|
+
raise "Gem #{gem_name} was found, but we could not load the file '#{r2}'. You may need to use :require=>x.........."
|
53
|
+
end
|
49
54
|
end
|
50
55
|
end
|
51
56
|
|
@@ -151,7 +156,7 @@ module SimpleWorker
|
|
151
156
|
# puts 'run_local'
|
152
157
|
set_auto_attributes
|
153
158
|
init_database
|
154
|
-
|
159
|
+
init_mailer
|
155
160
|
begin
|
156
161
|
run
|
157
162
|
rescue => ex
|
@@ -163,11 +168,11 @@ module SimpleWorker
|
|
163
168
|
end
|
164
169
|
end
|
165
170
|
|
166
|
-
|
171
|
+
def init_mailer
|
167
172
|
if SimpleWorker.config.mailer
|
168
173
|
require 'action_mailer'
|
169
|
-
|
170
|
-
|
174
|
+
ActionMailer::Base.raise_delivery_errors = true
|
175
|
+
ActionMailer::Base.smtp_settings = (SimpleWorker.config.mailer)
|
171
176
|
end
|
172
177
|
end
|
173
178
|
|
@@ -212,9 +217,8 @@ module SimpleWorker
|
|
212
217
|
upload_if_needed(options)
|
213
218
|
|
214
219
|
response = SimpleWorker.service.queue(self.class.name, sw_get_data, options)
|
215
|
-
|
216
|
-
|
217
|
-
@task_id = response["task_id"]
|
220
|
+
SimpleWorker.service.logger.debug 'queue response=' + response.inspect
|
221
|
+
@task_id = response["tasks"][0]["id"]
|
218
222
|
response
|
219
223
|
end
|
220
224
|
|
@@ -270,8 +274,8 @@ module SimpleWorker
|
|
270
274
|
upload_if_needed(schedule)
|
271
275
|
|
272
276
|
response = SimpleWorker.service.schedule(self.class.name, sw_get_data, schedule)
|
273
|
-
|
274
|
-
@schedule_id = response["
|
277
|
+
SimpleWorker.service.logger.debug 'schedule response=' + response.inspect
|
278
|
+
@schedule_id = response["schedules"][0]["id"]
|
275
279
|
response
|
276
280
|
end
|
277
281
|
|
@@ -408,6 +412,7 @@ module SimpleWorker
|
|
408
412
|
self.instance_variables.each do |iv|
|
409
413
|
payload[iv] = instance_variable_get(iv)
|
410
414
|
end
|
415
|
+
data['class_name'] = self.class.name
|
411
416
|
data[:attr_encoded] = Base64.encode64(payload.to_json)
|
412
417
|
data[:file_name] = File.basename(self.class.instance_variable_get(:@caller_file))
|
413
418
|
if defined?(Rails)
|
@@ -22,9 +22,11 @@ module SimpleWorker
|
|
22
22
|
end
|
23
23
|
options[:version] = SimpleWorker.api_version
|
24
24
|
options[:logger] = SimpleWorker.logger
|
25
|
-
super("
|
25
|
+
super("worker-aws-us-east-1.iron.io", token, options)
|
26
26
|
self.host = self.config.host if self.config && self.config.host
|
27
|
-
|
27
|
+
# automerge simple worker gem and dependenices
|
28
|
+
self.config.merge_gem('rest-client')
|
29
|
+
self.config.merge_gem('simple_worker')
|
28
30
|
SimpleWorker.logger.info 'SimpleWorker initialized.'
|
29
31
|
SimpleWorker.logger.debug ' host = ' + self.host.inspect
|
30
32
|
end
|
@@ -35,8 +37,6 @@ module SimpleWorker
|
|
35
37
|
def upload(filename, class_name, options={})
|
36
38
|
name = options[:name] || class_name
|
37
39
|
project_id = get_project_id(options)
|
38
|
-
# puts "Uploading #{class_name}"
|
39
|
-
# check whether it should upload again
|
40
40
|
tmp = Dir.tmpdir()
|
41
41
|
md5file = "simple_worker_#{class_name.gsub("::", ".")}_#{token[0, 8]}.md5"
|
42
42
|
existing_md5 = nil
|
@@ -44,7 +44,7 @@ module SimpleWorker
|
|
44
44
|
if File.exists?(md5_f)
|
45
45
|
existing_md5 = IO.read(md5_f)
|
46
46
|
end
|
47
|
-
# Check for code changes.
|
47
|
+
# Check for code changes.
|
48
48
|
md5 = Digest::MD5.hexdigest(File.read(filename))
|
49
49
|
new_code = false
|
50
50
|
if self.config.force_upload || md5 != existing_md5
|
@@ -125,12 +125,8 @@ module SimpleWorker
|
|
125
125
|
#tmp_file = File.join(Dir.tmpdir(), File.basename(filename))
|
126
126
|
tmp_file = File.join(Dir.tmpdir(), 'runner.rb')
|
127
127
|
File.open(tmp_file, "w") do |f|
|
128
|
-
|
129
|
-
|
130
|
-
f.write line
|
131
|
-
end
|
132
|
-
end
|
133
|
-
f.write("begin\n")#error handling block start
|
128
|
+
|
129
|
+
f.write("begin\n") #error handling block start
|
134
130
|
f.write("
|
135
131
|
# Find environment (-e)
|
136
132
|
dirname = ''
|
@@ -155,13 +151,13 @@ ARGV.each do |arg|
|
|
155
151
|
end
|
156
152
|
require 'json'
|
157
153
|
")
|
158
|
-
|
159
|
-
|
154
|
+
# require merged gems
|
155
|
+
merged_gems.each_pair do |k, gem|
|
160
156
|
SimpleWorker.logger.debug "Bundling gem #{gem[:name]}..."
|
161
157
|
if gem[:merge]
|
162
158
|
f.write "$LOAD_PATH << File.join(File.dirname(__FILE__), '/gems/#{gem[:name]}/lib')\n"
|
163
159
|
end
|
164
|
-
# unless gem[:no_require]
|
160
|
+
# unless gem[:no_require]
|
165
161
|
SimpleWorker.logger.debug 'writing requires: ' + gem[:require].inspect
|
166
162
|
if gem[:require].nil?
|
167
163
|
gem[:require] = []
|
@@ -173,11 +169,17 @@ require 'json'
|
|
173
169
|
SimpleWorker.logger.debug 'adding require to file ' + r.to_s
|
174
170
|
f.write "require '#{r}'\n"
|
175
171
|
end
|
176
|
-
|
177
|
-
|
172
|
+
end
|
173
|
+
|
174
|
+
|
175
|
+
File.open(File.join(File.dirname(__FILE__), "server", 'runner.rb'), 'r') do |fr|
|
176
|
+
while line = fr.gets
|
177
|
+
f.write line
|
178
|
+
end
|
179
|
+
end
|
178
180
|
|
179
181
|
# load job data
|
180
|
-
f.write("
|
182
|
+
f.write("
|
181
183
|
# Change to user directory
|
182
184
|
#puts 'dirname=' + dirname.inspect
|
183
185
|
Dir.chdir(dirname)
|
@@ -185,11 +187,8 @@ Dir.chdir(dirname)
|
|
185
187
|
job_data = JSON.load(File.open(task_data_file))
|
186
188
|
puts 'job_data=' + job_data.inspect
|
187
189
|
sw_config = job_data['sw_config']
|
188
|
-
init_database_connection(sw_config)
|
189
|
-
init_mailer(sw_config)
|
190
190
|
")
|
191
191
|
|
192
|
-
f.write("require 'simple_worker'\n")
|
193
192
|
|
194
193
|
# add some rails stuff if using Rails
|
195
194
|
if defined?(Rails)
|
@@ -204,22 +203,18 @@ end
|
|
204
203
|
"
|
205
204
|
end
|
206
205
|
|
207
|
-
if SimpleWorker.config.
|
208
|
-
|
206
|
+
if SimpleWorker.config.extra_requires
|
207
|
+
SimpleWorker.config.extra_requires.each do |r|
|
208
|
+
f.write "require '#{r}'\n"
|
209
|
+
end
|
209
210
|
end
|
210
|
-
|
211
211
|
if merged_mailers && !merged_mailers.empty?
|
212
212
|
# todo: isn't 'action_mailer already required in railtie?
|
213
213
|
f.write "require 'action_mailer'\n"
|
214
|
+
f.write "init_mailer(sw_config)\n"
|
214
215
|
f.write "ActionMailer::Base.prepend_view_path('templates')\n"
|
215
216
|
end
|
216
|
-
|
217
|
-
|
218
|
-
if SimpleWorker.config.extra_requires
|
219
|
-
SimpleWorker.config.extra_requires.each do |r|
|
220
|
-
f.write "require '#{r}'\n"
|
221
|
-
end
|
222
|
-
end
|
217
|
+
f.write "init_database_connection(sw_config)"
|
223
218
|
|
224
219
|
File.open(File.join(File.dirname(__FILE__), 'server', 'overrides.rb'), 'r') do |fr|
|
225
220
|
while line = fr.gets
|
@@ -239,8 +234,6 @@ end
|
|
239
234
|
#f.write File.open(filename, 'r') { |mo| mo.read }
|
240
235
|
f.write("require_relative '#{File.basename(filename)}'")
|
241
236
|
|
242
|
-
|
243
|
-
|
244
237
|
f.write("
|
245
238
|
SimpleWorker.disable_queueing()
|
246
239
|
runner_class = get_class_to_run(job_data['class_name'])
|
@@ -381,7 +374,7 @@ end
|
|
381
374
|
"projects/#{project_id}/"
|
382
375
|
end
|
383
376
|
|
384
|
-
def wait_until_complete(task_id)
|
377
|
+
def wait_until_complete(task_id, options={})
|
385
378
|
tries = 0
|
386
379
|
status = nil
|
387
380
|
sleep 1
|
@@ -398,7 +391,7 @@ end
|
|
398
391
|
|
399
392
|
def add_sw_params(hash_to_send)
|
400
393
|
# todo: remove secret key?? Can use worker service from within a worker without it now
|
401
|
-
hash_to_send["
|
394
|
+
hash_to_send["oauth"] = self.token
|
402
395
|
hash_to_send["api_version"] = SimpleWorker.api_version
|
403
396
|
end
|
404
397
|
|
@@ -408,42 +401,46 @@ end
|
|
408
401
|
end
|
409
402
|
end
|
410
403
|
|
411
|
-
def enqueue(
|
412
|
-
queue(
|
404
|
+
def enqueue(name, data={}, options={})
|
405
|
+
queue(name, data, options)
|
413
406
|
end
|
414
407
|
|
415
|
-
#
|
408
|
+
# name: The name of previously upload worker code, eg: MySuperWorker
|
416
409
|
# data: Arbitrary hash of your own data that your task will need to run.
|
417
|
-
def queue(
|
418
|
-
puts "Queuing #{
|
410
|
+
def queue(name, data={}, options={})
|
411
|
+
puts "Queuing #{name}..."
|
419
412
|
check_config
|
420
413
|
if !data.is_a?(Array)
|
421
414
|
data = [data]
|
422
415
|
end
|
423
416
|
# Now we need to add class_name to the payload
|
417
|
+
tasks = []
|
424
418
|
data.each do |d|
|
425
|
-
d['class_name'] = class_name
|
419
|
+
d['class_name'] = name unless d['class_name']
|
420
|
+
task = {}
|
421
|
+
task["payload"] = d.to_json
|
422
|
+
task["code_name"] = name
|
423
|
+
task["priority"] = options[:priority] if options[:priority]
|
424
|
+
task["timeout"] = options[:timeout] if options[:timeout]
|
425
|
+
tasks << task
|
426
426
|
end
|
427
|
-
name = options[:name] ||
|
427
|
+
name = options[:name] || name
|
428
428
|
hash_to_send = {}
|
429
|
-
hash_to_send["payload"] = data
|
430
|
-
hash_to_send["class_name"] = class_name
|
431
|
-
hash_to_send["name"] = name
|
432
|
-
hash_to_send["priority"] = options[:priority] if options[:priority]
|
433
429
|
hash_to_send["options"] = options
|
430
|
+
hash_to_send["tasks"] = tasks
|
434
431
|
add_sw_params(hash_to_send)
|
435
432
|
if defined?(RAILS_ENV)
|
436
433
|
# todo: REMOVE THIS
|
437
434
|
hash_to_send["rails_env"] = RAILS_ENV
|
438
435
|
end
|
439
|
-
return queue_raw(
|
436
|
+
return queue_raw(name, hash_to_send, options)
|
440
437
|
end
|
441
438
|
|
442
|
-
def queue_raw(
|
439
|
+
def queue_raw(name, data={}, options={})
|
443
440
|
params = nil
|
444
441
|
hash_to_send = data
|
445
|
-
hash_to_send["class_name"] =
|
446
|
-
hash_to_send["name"] =
|
442
|
+
#hash_to_send["class_name"] = name unless hash_to_send["class_name"]
|
443
|
+
hash_to_send["name"] = name unless hash_to_send["name"]
|
447
444
|
uri = project_url_prefix(get_project_id(options)) + "tasks"
|
448
445
|
SimpleWorker.logger.debug 'queue_raw , uri = ' + uri
|
449
446
|
ret = post(uri, hash_to_send)
|
@@ -460,19 +457,20 @@ end
|
|
460
457
|
# - end_at: Scheduled task will stop running after this date (optional, if ommitted, runs forever or until cancelled)
|
461
458
|
# - run_times: Task will run exactly :run_times. For instance if :run_times is 5, then the task will run 5 times.
|
462
459
|
#
|
463
|
-
def schedule(
|
464
|
-
puts "Scheduling #{
|
460
|
+
def schedule(name, data, schedule)
|
461
|
+
puts "Scheduling #{name}..."
|
465
462
|
raise "Schedule must be a hash." if !schedule.is_a? Hash
|
466
|
-
# if !data.is_a?(Array)
|
467
|
-
# data = [data]
|
468
|
-
# end
|
469
463
|
hash_to_send = {}
|
470
|
-
|
471
|
-
|
472
|
-
|
464
|
+
schedules = []
|
465
|
+
schedule["payload"] = data.to_json
|
466
|
+
schedule["name"] = name unless schedule["name"]
|
467
|
+
schedule["code_name"] = name unless schedule["code_name"]
|
468
|
+
schedules << schedule
|
469
|
+
hash_to_send["schedules"] = schedules
|
473
470
|
add_sw_params(hash_to_send)
|
474
471
|
# puts ' about to send ' + hash_to_send.inspect
|
475
|
-
|
472
|
+
uri = project_url_prefix(get_project_id(data)) + "schedules"
|
473
|
+
ret = post(uri, hash_to_send)
|
476
474
|
ret
|
477
475
|
end
|
478
476
|
|
@@ -542,9 +540,9 @@ end
|
|
542
540
|
ret
|
543
541
|
end
|
544
542
|
|
545
|
-
def schedule_status(schedule_id)
|
543
|
+
def schedule_status(schedule_id, options={})
|
546
544
|
data = {"schedule_id"=>schedule_id}
|
547
|
-
ret = get("
|
545
|
+
ret = get("#{project_url_prefix(get_project_id(options))}schedules/#{schedule_id}", data)
|
548
546
|
ret
|
549
547
|
end
|
550
548
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: simple_worker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 6
|
5
|
-
version: 2.0.0.beta.
|
5
|
+
version: 2.0.0.beta.15
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Travis Reeder
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-10-
|
13
|
+
date: 2011-10-27 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: zip
|
@@ -34,6 +34,17 @@ dependencies:
|
|
34
34
|
version: "0"
|
35
35
|
type: :runtime
|
36
36
|
version_requirements: *id002
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: patron
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: "0"
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id003
|
37
48
|
description: The official SimpleWorker gem for http://www.simpleworker.com
|
38
49
|
email: travis@appoxy.com
|
39
50
|
executables: []
|