tq 0.1.6 → 0.2.1

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: f1189c610b90b4d6e1af73a3e075981588797bff
4
- data.tar.gz: dd0f3598d6261f985e8830d0bb73d848f29fce0c
3
+ metadata.gz: 877e9730d05610f3b211c7a0d69817f60149bde4
4
+ data.tar.gz: eb2d73a1f7e5a63659fe53041171bde055e59523
5
5
  SHA512:
6
- metadata.gz: 0684ba5f822f4ee215c131d7c56d0f9f939309b8faa85c8cebcf140da75b9e0212586dac3e093acffb3b224af28c2d855aa23c3dbf4c3171e9678bb6b8c01bab
7
- data.tar.gz: a178c5c079388733ad77f4e075bd1ecc14346a48aad514275a48d5a08161dbbe30ecf77dffef32c0d7ca8a5cc3f8ddf57d26752e4f268362cca0e691f35c5d6d
6
+ metadata.gz: 9c2539a74728b068c962eab6e1637559664e1a5a74514623893b756166c1246641c5b33dc5892e671ada06a7e2760bba2453137b0ba98f74813c729bbdbaed3b
7
+ data.tar.gz: 2981fa8c831cf086873d2d9dfd2fef886533dc01baaa5521b0d4ea2f6f6a701ed37a165299f558a92ba3397d98ddab54415f1658bad433192335a261063b9b45
@@ -155,7 +155,11 @@ module TQ
155
155
  def _run(qin, qout, qerr)
156
156
  tasks = qin.lease!
157
157
  Parallel.each(tasks, :in_threads => @options['concurrency']) do |task|
158
- @worker.new(qin, qout, qerr, inherited_env).call(task)
158
+ if task.try?
159
+ @worker.new(qin, qout, qerr, inherited_env).call(task)
160
+ else
161
+ qin.finish!(task)
162
+ end
159
163
  end
160
164
  end
161
165
 
@@ -5,7 +5,11 @@ module TQ
5
5
 
6
6
  class Queue
7
7
 
8
- DEFAULT_OPTIONS = { 'lease_secs' => 60, 'num_tasks' => 1 }
8
+ DEFAULT_OPTIONS = {
9
+ 'lease_secs' => 60,
10
+ 'num_tasks' => 1,
11
+ 'max_tries' => -1
12
+ }
9
13
 
10
14
  attr_reader :client, :api
11
15
  def initialize(client, api, options={})
@@ -25,6 +29,10 @@ module TQ
25
29
  options({'name' => _})
26
30
  end
27
31
 
32
+ def option(key)
33
+ @options[key]
34
+ end
35
+
28
36
  def lease!(opts={})
29
37
  opts = @options.merge(opts)
30
38
  results = client.execute!(
@@ -86,7 +94,15 @@ module TQ
86
94
  private
87
95
 
88
96
  def new_task(t)
89
- Task.new(self, t['id'], timestamp_time(t['leaseTimestamp']), decode(t.payloadBase64), t)
97
+ Task.new(
98
+ self,
99
+ t['id'],
100
+ timestamp_time(t['leaseTimestamp']),
101
+ t['retry_count'],
102
+ t['tag'],
103
+ decode(t.payloadBase64),
104
+ t
105
+ )
90
106
  end
91
107
 
92
108
  def timestamp_time(t)
@@ -103,7 +119,7 @@ module TQ
103
119
 
104
120
  end
105
121
 
106
- class Task < Struct.new(:queue, :id, :expires, :payload, :raw)
122
+ class Task < Struct.new(:queue, :id, :expires, :tries, :tag, :payload, :raw)
107
123
 
108
124
  def initialize(*args)
109
125
  super
@@ -134,6 +150,11 @@ module TQ
134
150
  self.expires < @clock.now
135
151
  end
136
152
 
153
+ def try?
154
+ max = self.queue.option('max_tries')
155
+ return (max == -1 or self.tries < max)
156
+ end
157
+
137
158
  end
138
159
 
139
160
  end
@@ -1,4 +1,4 @@
1
1
 
2
2
  module TQ
3
- VERSION = '0.1.6'
3
+ VERSION = '0.2.1'
4
4
  end
@@ -26,18 +26,33 @@ module TestUtils
26
26
  attr_reader :project, :queue
27
27
  def initialize(project,queue)
28
28
  @project, @queue = project, queue
29
+ @service_auth = false
29
30
  end
30
31
 
31
32
  def auth_files(secrets,creds)
32
33
  @secrets_file, @creds_file = secrets, creds
34
+ @service_auth = false
35
+ return self
36
+ end
37
+
38
+ def service_auth_files(issuer,p12)
39
+ @secrets_issuer, @secrets_p12 = issuer, p12
40
+ @service_auth = true
33
41
  return self
34
42
  end
35
43
 
36
44
  def authorized_client
37
- # @authorized_client ||= TQ::App.new('test_app',nil).service_auth!(File.read(SERVICE_ISSUER_FILE).chomp, SERVICE_P12_FILE)
38
- @authorized_client ||= TQ::App.new('test_app',nil).auth!(@secrets_file, @creds_file)
45
+ @authorized_client ||= (
46
+ if @service_auth
47
+ TQ::App.new('test_app',nil).service_auth!(
48
+ File.read(@secrets_issuer).chomp, @secrets_p12
49
+ )
50
+ else
51
+ TQ::App.new('test_app',nil).auth!(@secrets_file, @creds_file)
52
+ end
53
+ )
39
54
  end
40
-
55
+
41
56
  # Note: inaccurate, don't use
42
57
  def peek()
43
58
  client, api = authorized_client
@@ -39,7 +39,7 @@ class AppRunTests < Minitest::Spec
39
39
 
40
40
 
41
41
  def queue_helper(project,queue)
42
- TestUtils::QueueHelper.new(project,queue).auth_files(CLIENT_SECRETS_FILE, CREDENTIALS_FILE)
42
+ TestUtils::QueueHelper.new(project,queue).service_auth_files(SERVICE_ISSUER_FILE, SERVICE_P12_FILE)
43
43
  end
44
44
 
45
45
  def tasks_on_queue(project,queue)
@@ -54,6 +54,10 @@ class AppRunTests < Minitest::Spec
54
54
  q = queue_helper(project,queue)
55
55
  tasks.each do |task| q.push!(task) end
56
56
  end
57
+
58
+ def service_run!(app)
59
+ app.service_run! File.read(SERVICE_ISSUER_FILE).chomp, SERVICE_P12_FILE
60
+ end
57
61
 
58
62
 
59
63
  describe "run!" do
@@ -113,7 +117,8 @@ class AppRunTests < Minitest::Spec
113
117
  app = TQ::App.new('test_app/0.0.0', mock_handler_class)
114
118
  .project(TASKQUEUE_PROJECT_ID)
115
119
  .stdin({ 'name' => 'test', 'num_tasks' => expected_calls, 'lease_secs' => TASKQUEUE_LEASE_SECS })
116
- app.run! CLIENT_SECRETS_FILE, CREDENTIALS_FILE
120
+ # app.run! CLIENT_SECRETS_FILE, CREDENTIALS_FILE
121
+ service_run! app
117
122
 
118
123
  # assertions
119
124
  assert_equal expected_calls, actual_calls,
@@ -141,8 +146,9 @@ class AppRunTests < Minitest::Spec
141
146
  app = TQ::App.new('test_app/0.0.0', DoNothingWorker)
142
147
  .project(TASKQUEUE_PROJECT_ID)
143
148
  .stdin({ 'name' => 'test', 'num_tasks' => 1, 'lease_secs' => TASKQUEUE_LEASE_SECS })
144
- app.run! CLIENT_SECRETS_FILE, CREDENTIALS_FILE
145
-
149
+ # app.run! CLIENT_SECRETS_FILE, CREDENTIALS_FILE
150
+ service_run! app
151
+
146
152
  sleep TASKQUEUE_LEASE_SECS + 1
147
153
  actual_tasks = clear_queue!(TASKQUEUE_PROJECT_ID,'test')
148
154
 
@@ -182,7 +188,8 @@ class AppRunTests < Minitest::Spec
182
188
  .project(TASKQUEUE_PROJECT_ID)
183
189
  .stdin({ 'name' => 'test', 'num_tasks' => 1, 'lease_secs' => TASKQUEUE_LEASE_SECS })
184
190
  .stdout({ 'name' => 'log' })
185
- app.run! CLIENT_SECRETS_FILE, CREDENTIALS_FILE
191
+ # app.run! CLIENT_SECRETS_FILE, CREDENTIALS_FILE
192
+ service_run! app
186
193
 
187
194
  sleep TASKQUEUE_LEASE_SECS + 1
188
195
  actual_output_tasks = clear_queue!(TASKQUEUE_PROJECT_ID,'log')
@@ -228,10 +235,119 @@ class AppRunTests < Minitest::Spec
228
235
  app = TQ::App.new('test_app/0.0.0', ExtendWorker)
229
236
  .project(TASKQUEUE_PROJECT_ID)
230
237
  .stdin({ 'name' => 'test', 'num_tasks' => 1, 'lease_secs' => TASKQUEUE_LEASE_SECS + 2 })
231
- app.run! CLIENT_SECRETS_FILE, CREDENTIALS_FILE
238
+ # app.run! CLIENT_SECRETS_FILE, CREDENTIALS_FILE
239
+ service_run! app
232
240
 
233
241
  end
234
242
 
243
+ it 'should retry tasks indefinitely by default' do
244
+
245
+ # setup
246
+ expected_tasks = [
247
+ { 'What is your name?' => 'Sir Lancelot', 'What is your quest?' => 'To seek the holy grail', 'What is your favorite color?' => 'blue' }
248
+ ]
249
+ push_tasks!(TASKQUEUE_PROJECT_ID,'test', expected_tasks)
250
+
251
+ # expectations
252
+ mock_handler_class = MiniTest::Mock.new
253
+ mock_handler = MiniTest::Mock.new
254
+
255
+ ## expect constructor receives task queue as first param
256
+ expected_calls = 3
257
+ (0...expected_calls).each do
258
+ mock_handler_class.expect(:new, mock_handler) do |*args|
259
+ args.first.respond_to?('finish!')
260
+ end
261
+ end
262
+
263
+ ## expect :call for each queued task up to expected_calls
264
+ actual_calls = 0
265
+ (0...expected_calls).each do
266
+ mock_handler.expect(:call, true) do |actual_task|
267
+ actual_calls += 1
268
+ end
269
+ end
270
+
271
+ # execution
272
+ app = TQ::App.new('test_app/0.0.0', mock_handler_class)
273
+ .project(TASKQUEUE_PROJECT_ID)
274
+ .stdin({ 'name' => 'test',
275
+ 'num_tasks' => 1,
276
+ 'lease_secs' => TASKQUEUE_LEASE_SECS
277
+ })
278
+ .stdout({ 'name' => 'log' })
279
+
280
+ service_run! app
281
+ sleep TASKQUEUE_LEASE_SECS + 1
282
+ service_run! app
283
+ sleep TASKQUEUE_LEASE_SECS + 1
284
+ service_run! app
285
+
286
+ # assertion
287
+
288
+ assert_equal expected_calls, actual_calls,
289
+ "Expected #{expected_calls} worker calls, was #{actual_calls}"
290
+
291
+ mock_handler_class.verify
292
+ mock_handler.verify
293
+
294
+ end
295
+
296
+ it 'should only run if current task retry count is less than queue max_tries' do
297
+
298
+ # setup
299
+ expected_tasks = [
300
+ { 'What is your name?' => 'Sir Lancelot', 'What is your quest?' => 'To seek the holy grail', 'What is your favorite color?' => 'blue' }
301
+ ]
302
+ push_tasks!(TASKQUEUE_PROJECT_ID,'test', expected_tasks)
303
+
304
+ # expectations
305
+ mock_handler_class = MiniTest::Mock.new
306
+ mock_handler = MiniTest::Mock.new
307
+
308
+ ## expect constructor receives task queue as first param
309
+ max_tries = 2
310
+ expected_calls = max_tries
311
+ (0...expected_calls).each do
312
+ mock_handler_class.expect(:new, mock_handler) do |*args|
313
+ args.first.respond_to?('finish!')
314
+ end
315
+ end
316
+
317
+ ## expect :call for each queued task up to expected_calls
318
+ actual_calls = 0
319
+ (0...max_tries).each do
320
+ mock_handler.expect(:call, true) do |actual_task|
321
+ actual_calls += 1
322
+ end
323
+ end
324
+
325
+ # execution
326
+ app = TQ::App.new('test_app/0.0.0', mock_handler_class)
327
+ .project(TASKQUEUE_PROJECT_ID)
328
+ .stdin({ 'name' => 'test',
329
+ 'num_tasks' => 1,
330
+ 'lease_secs' => TASKQUEUE_LEASE_SECS,
331
+ 'max_tries' => max_tries
332
+ })
333
+ .stdout({ 'name' => 'log' })
334
+
335
+ service_run! app
336
+ sleep TASKQUEUE_LEASE_SECS + 1
337
+ service_run! app
338
+ sleep TASKQUEUE_LEASE_SECS + 1
339
+ service_run! app
340
+
341
+ # assertion
342
+ assert_equal expected_calls, actual_calls,
343
+ "Expected #{expected_calls} worker calls, was #{actual_calls}"
344
+
345
+ mock_handler_class.verify
346
+ mock_handler.verify
347
+
348
+ end
349
+
350
+
235
351
  end
236
352
 
237
353
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Gjertsen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-03 00:00:00.000000000 Z
11
+ date: 2016-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-api-client
@@ -91,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
91
  version: '0'
92
92
  requirements: []
93
93
  rubyforge_project:
94
- rubygems_version: 2.4.5
94
+ rubygems_version: 2.5.1
95
95
  signing_key:
96
96
  specification_version: 4
97
97
  summary: Ruby client for Google App Engine TaskQueue (REST API)