tq 0.1.6 → 0.2.1

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.
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)