fairway 0.2.7 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/go/queue_test.go CHANGED
@@ -23,16 +23,128 @@ func QueueSpec(c gospec.Context) {
23
23
  conn.Deliver(msg1)
24
24
  conn.Deliver(msg2)
25
25
 
26
- queueName, message := queue.Pull()
26
+ r := config.Pool.Get()
27
+ defer r.Close()
28
+
29
+ count, _ := redis.Int(r.Do("llen", "fairway:myqueue:default"))
30
+ c.Expect(count, Equals, 2)
31
+ count, _ = redis.Int(r.Do("scard", "fairway:myqueue:active_facets"))
32
+ c.Expect(count, Equals, 1)
33
+ count, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
34
+ c.Expect(count, Equals, 1)
35
+ count, _ = redis.Int(r.Do("get", "fairway:myqueue:limit"))
36
+ c.Expect(count, Equals, 0)
37
+ count, _ = redis.Int(r.Do("get", "fairway:myqueue:inflight"))
38
+ c.Expect(count, Equals, 0)
39
+ count, _ = redis.Int(r.Do("hget", "fairway:myqueue:facet_pool", "default"))
40
+ c.Expect(count, Equals, 1)
41
+
42
+ queueName, message := queue.Pull(-1)
43
+
44
+ count, _ = redis.Int(r.Do("llen", "fairway:myqueue:default"))
45
+ c.Expect(count, Equals, 1)
46
+ count, _ = redis.Int(r.Do("scard", "fairway:myqueue:active_facets"))
47
+ c.Expect(count, Equals, 1)
48
+ count, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
49
+ c.Expect(count, Equals, 1)
50
+ count, _ = redis.Int(r.Do("get", "fairway:myqueue:limit"))
51
+ c.Expect(count, Equals, 0)
52
+ count, _ = redis.Int(r.Do("get", "fairway:myqueue:inflight"))
53
+ c.Expect(count, Equals, 0)
54
+ count, _ = redis.Int(r.Do("hget", "fairway:myqueue:facet_pool", "default"))
55
+ c.Expect(count, Equals, 1)
56
+
27
57
  c.Expect(queueName, Equals, "myqueue")
28
58
  c.Expect(message.json(), Equals, msg1.json())
29
59
 
30
- queueName, message = queue.Pull()
60
+ queueName, message = queue.Pull(-1)
31
61
  c.Expect(queueName, Equals, "myqueue")
32
62
  c.Expect(message.json(), Equals, msg2.json())
33
63
  })
34
64
 
35
- c.Specify("pulls from facets of the queue in round-robin", func() {
65
+ c.Specify("places pulled message on inflight sorted set until acknowledged", func() {
66
+ msg1, _ := NewMsg(map[string]string{"name": "mymessage1"})
67
+
68
+ conn.Deliver(msg1)
69
+
70
+ c.Expect(len(queue.Inflight()), Equals, 0)
71
+
72
+ queueName, message := queue.Pull(100)
73
+ c.Expect(queueName, Equals, "myqueue")
74
+ c.Expect(message.json(), Equals, msg1.json())
75
+
76
+ c.Expect(len(queue.Inflight()), Equals, 1)
77
+ c.Expect(queue.Inflight()[0], Equals, msg1.json())
78
+
79
+ queue.Ack(msg1)
80
+
81
+ c.Expect(len(queue.Inflight()), Equals, 0)
82
+ })
83
+
84
+ c.Specify("pulls from inflight message set if messages are unacknowledged", func() {
85
+ msg1, _ := NewMsg(map[string]string{"name": "mymessage1"})
86
+ msg2, _ := NewMsg(map[string]string{"name": "mymessage2"})
87
+
88
+ conn.Deliver(msg1)
89
+ conn.Deliver(msg2)
90
+
91
+ queueName, message := queue.Pull(0)
92
+ c.Expect(queueName, Equals, "myqueue")
93
+ c.Expect(message.json(), Equals, msg1.json())
94
+
95
+ queueName, message = queue.Pull(10)
96
+ c.Expect(queueName, Equals, "myqueue")
97
+ c.Expect(message.json(), Equals, msg1.json())
98
+
99
+ queueName, message = queue.Pull(10)
100
+ c.Expect(queueName, Equals, "myqueue")
101
+ c.Expect(message.json(), Equals, msg2.json())
102
+ })
103
+
104
+ c.Specify("allows puller to ping to keep message inflight", func() {
105
+ msg1, _ := NewMsg(map[string]string{"name": "mymessage1"})
106
+ msg2, _ := NewMsg(map[string]string{"name": "mymessage2"})
107
+
108
+ conn.Deliver(msg1)
109
+ conn.Deliver(msg2)
110
+
111
+ queueName, message := queue.Pull(0)
112
+ c.Expect(queueName, Equals, "myqueue")
113
+ c.Expect(message.json(), Equals, msg1.json())
114
+
115
+ // Extends time before message is resent
116
+ queue.Ping(msg1, 10)
117
+
118
+ queueName, message = queue.Pull(10)
119
+ c.Expect(queueName, Equals, "myqueue")
120
+ c.Expect(message.json(), Equals, msg2.json())
121
+
122
+ // Sets time for message to resend to now
123
+ queue.Ping(msg1, 0)
124
+
125
+ queueName, message = queue.Pull(10)
126
+ c.Expect(queueName, Equals, "myqueue")
127
+ c.Expect(message.json(), Equals, msg1.json())
128
+ })
129
+
130
+ c.Specify("set limits messages inflight", func() {
131
+ limit, err := queue.InflightLimit()
132
+
133
+ c.Expect(limit, Equals, 0)
134
+ c.Expect(err, IsNil)
135
+
136
+ queue.SetInflightLimit(1)
137
+
138
+ limit, err = queue.InflightLimit()
139
+
140
+ c.Expect(limit, Equals, 1)
141
+ c.Expect(err, IsNil)
142
+ })
143
+
144
+ c.Specify("limits messages inflight", func() {
145
+ r := config.Pool.Get()
146
+ defer r.Close()
147
+
36
148
  config.Facet = func(msg *Msg) string {
37
149
  str, _ := msg.Get("facet").String()
38
150
  return str
@@ -46,12 +158,358 @@ func QueueSpec(c gospec.Context) {
46
158
  conn.Deliver(msg2)
47
159
  conn.Deliver(msg3)
48
160
 
49
- _, message := queue.Pull()
161
+ queue.SetInflightLimit(1)
162
+
163
+ _, message := queue.Pull(2)
50
164
  c.Expect(message.json(), Equals, msg1.json())
51
- _, message = queue.Pull()
165
+
166
+ count, _ := redis.Int(r.Do("get", "fairway:myqueue:1:inflight"))
167
+ c.Expect(count, Equals, 1)
168
+
169
+ _, message = queue.Pull(2)
52
170
  c.Expect(message.json(), Equals, msg3.json())
53
- _, message = queue.Pull()
171
+
172
+ count, _ = redis.Int(r.Do("get", "fairway:myqueue:1:inflight"))
173
+ c.Expect(count, Equals, 1)
174
+
175
+ count, _ = redis.Int(r.Do("get", "fairway:myqueue:2:inflight"))
176
+ c.Expect(count, Equals, 1)
177
+
178
+ _, message = queue.Pull(2)
179
+ c.Expect(message, IsNil)
180
+ _, message = queue.Pull(2)
181
+ c.Expect(message, IsNil)
182
+
183
+ count, _ = redis.Int(r.Do("get", "fairway:myqueue:1:inflight"))
184
+ c.Expect(count, Equals, 1)
185
+
186
+ count, _ = redis.Int(r.Do("get", "fairway:myqueue:2:inflight"))
187
+ c.Expect(count, Equals, 1)
188
+
189
+ queue.Ack(msg1)
190
+ queue.Ack(msg1)
191
+ queue.Ack(msg1)
192
+ queue.Ack(msg1)
193
+ queue.Ack(msg1)
194
+
195
+ count, err := redis.Int(r.Do("get", "fairway:myqueue:1:inflight"))
196
+ c.Expect(count, Equals, 0)
197
+ c.Expect(err, IsNil)
198
+
199
+ count, _ = redis.Int(r.Do("get", "fairway:myqueue:2:inflight"))
200
+ c.Expect(count, Equals, 1)
201
+
202
+ _, message = queue.Pull(2)
54
203
  c.Expect(message.json(), Equals, msg2.json())
204
+
205
+ count, _ = redis.Int(r.Do("get", "fairway:myqueue:1:inflight"))
206
+ c.Expect(count, Equals, 1)
207
+
208
+ count, _ = redis.Int(r.Do("get", "fairway:myqueue:2:inflight"))
209
+ c.Expect(count, Equals, 1)
210
+ })
211
+
212
+ c.Specify("prevents overlimit messages when all messages are inflight", func() {
213
+ r := config.Pool.Get()
214
+ defer r.Close()
215
+
216
+ config.Facet = func(msg *Msg) string {
217
+ str, _ := msg.Get("facet").String()
218
+ return str
219
+ }
220
+
221
+ msg1, _ := NewMsg(map[string]string{"facet": "1", "name": "mymessage1"})
222
+ msg2, _ := NewMsg(map[string]string{"facet": "1", "name": "mymessage2"})
223
+ msg3, _ := NewMsg(map[string]string{"facet": "1", "name": "mymessage3"})
224
+
225
+ queue.SetInflightLimit(1)
226
+
227
+ active, _ := redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
228
+ c.Expect(len(active), Equals, 0)
229
+ fqueue, _ := redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
230
+ c.Expect(fqueue, Equals, 0)
231
+
232
+ conn.Deliver(msg1)
233
+
234
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
235
+ c.Expect(len(active), Equals, 1)
236
+ c.Expect(active[0], Equals, "1")
237
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
238
+ c.Expect(fqueue, Equals, 1)
239
+
240
+ _, message := queue.Pull(2)
241
+ c.Expect(message.json(), Equals, msg1.json())
242
+
243
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
244
+ c.Expect(len(active), Equals, 1)
245
+ c.Expect(active[0], Equals, "1")
246
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
247
+ c.Expect(fqueue, Equals, 0)
248
+
249
+ conn.Deliver(msg2)
250
+
251
+ _, message = queue.Pull(2)
252
+ c.Expect(message, IsNil)
253
+
254
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
255
+ c.Expect(len(active), Equals, 1)
256
+ c.Expect(active[0], Equals, "1")
257
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
258
+ c.Expect(fqueue, Equals, 0)
259
+
260
+ queue.Ack(msg1)
261
+
262
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
263
+ c.Expect(len(active), Equals, 1)
264
+ c.Expect(active[0], Equals, "1")
265
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
266
+ c.Expect(fqueue, Equals, 1)
267
+
268
+ _, message = queue.Pull(2)
269
+ c.Expect(message.json(), Equals, msg2.json())
270
+
271
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
272
+ c.Expect(len(active), Equals, 1)
273
+ c.Expect(active[0], Equals, "1")
274
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
275
+ c.Expect(fqueue, Equals, 0)
276
+
277
+ conn.Deliver(msg3)
278
+
279
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
280
+ c.Expect(len(active), Equals, 1)
281
+ c.Expect(active[0], Equals, "1")
282
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
283
+ c.Expect(fqueue, Equals, 0)
284
+
285
+ _, message = queue.Pull(2)
286
+ c.Expect(message, IsNil)
287
+
288
+ queue.Ack(msg2)
289
+
290
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
291
+ c.Expect(len(active), Equals, 1)
292
+ c.Expect(active[0], Equals, "1")
293
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
294
+ c.Expect(fqueue, Equals, 1)
295
+
296
+ _, message = queue.Pull(2)
297
+ c.Expect(message.json(), Equals, msg3.json())
298
+
299
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
300
+ c.Expect(len(active), Equals, 1)
301
+ c.Expect(active[0], Equals, "1")
302
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
303
+ c.Expect(fqueue, Equals, 0)
304
+
305
+ _, message = queue.Pull(2)
306
+ c.Expect(message, IsNil)
307
+
308
+ queue.Ack(msg3)
309
+
310
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
311
+ c.Expect(len(active), Equals, 0)
312
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
313
+ c.Expect(fqueue, Equals, 0)
314
+
315
+ msg4, _ := NewMsg(map[string]string{"facet": "1", "name": "mymessage4"})
316
+
317
+ conn.Deliver(msg4)
318
+
319
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
320
+ c.Expect(len(active), Equals, 1)
321
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
322
+ c.Expect(fqueue, Equals, 1)
323
+
324
+ _, message = queue.Pull(2)
325
+ c.Expect(message.json(), Equals, msg4.json())
326
+
327
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
328
+ c.Expect(len(active), Equals, 1)
329
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
330
+ c.Expect(fqueue, Equals, 0)
331
+
332
+ queue.Ack(msg4)
333
+
334
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
335
+ c.Expect(len(active), Equals, 0)
336
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
337
+ c.Expect(fqueue, Equals, 0)
338
+
339
+ _, message = queue.Pull(2)
340
+ c.Expect(message, IsNil)
341
+
342
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
343
+ c.Expect(len(active), Equals, 0)
344
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
345
+ c.Expect(fqueue, Equals, 0)
346
+ })
347
+
348
+ c.Specify("if inflight limit is 0, no limit", func() {
349
+ r := config.Pool.Get()
350
+ defer r.Close()
351
+
352
+ config.Facet = func(msg *Msg) string {
353
+ str, _ := msg.Get("facet").String()
354
+ return str
355
+ }
356
+
357
+ msg1, _ := NewMsg(map[string]string{"facet": "1", "name": "mymessage1"})
358
+ msg2, _ := NewMsg(map[string]string{"facet": "1", "name": "mymessage2"})
359
+ msg3, _ := NewMsg(map[string]string{"facet": "2", "name": "mymessage3"})
360
+
361
+ queue.SetInflightLimit(0)
362
+
363
+ conn.Deliver(msg1)
364
+ conn.Deliver(msg2)
365
+ conn.Deliver(msg3)
366
+
367
+ active, _ := redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
368
+ c.Expect(len(active), Equals, 2)
369
+ fqueue, _ := redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
370
+ c.Expect(fqueue, Equals, 2)
371
+
372
+ _, message := queue.Pull(2)
373
+ c.Expect(message.json(), Equals, msg1.json())
374
+
375
+ _, message = queue.Pull(2)
376
+ c.Expect(message.json(), Equals, msg3.json())
377
+
378
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
379
+ c.Expect(len(active), Equals, 2)
380
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
381
+ c.Expect(fqueue, Equals, 1)
382
+
383
+ _, message = queue.Pull(2)
384
+ c.Expect(message.json(), Equals, msg2.json())
385
+
386
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
387
+ c.Expect(len(active), Equals, 2)
388
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
389
+ c.Expect(fqueue, Equals, 0)
390
+
391
+ msg4, _ := NewMsg(map[string]string{"facet": "2", "name": "mymessage4"})
392
+
393
+ conn.Deliver(msg4)
394
+
395
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
396
+ c.Expect(len(active), Equals, 2)
397
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
398
+ c.Expect(fqueue, Equals, 1)
399
+
400
+ queue.Ack(msg1)
401
+ queue.Ack(msg2)
402
+
403
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
404
+ c.Expect(len(active), Equals, 1)
405
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
406
+ c.Expect(fqueue, Equals, 1)
407
+
408
+ _, message = queue.Pull(2)
409
+ c.Expect(message.json(), Equals, msg4.json())
410
+
411
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
412
+ c.Expect(len(active), Equals, 1)
413
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
414
+ c.Expect(fqueue, Equals, 0)
415
+
416
+ _, message = queue.Pull(2)
417
+ c.Expect(message, IsNil)
418
+
419
+ queue.Ack(msg3)
420
+
421
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
422
+ c.Expect(len(active), Equals, 1)
423
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
424
+ c.Expect(fqueue, Equals, 0)
425
+
426
+ queue.Ack(msg4)
427
+
428
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
429
+ c.Expect(len(active), Equals, 0)
430
+ fqueue, _ = redis.Int(r.Do("llen", "fairway:myqueue:facet_queue"))
431
+ c.Expect(fqueue, Equals, 0)
432
+
433
+ })
434
+
435
+ c.Specify("doesn't place pulled message on inflight sorted set if inflight is disabled", func() {
436
+ msg1, _ := NewMsg(map[string]string{"name": "mymessage1"})
437
+
438
+ conn.Deliver(msg1)
439
+
440
+ c.Expect(len(queue.Inflight()), Equals, 0)
441
+
442
+ queueName, message := queue.Pull(-1)
443
+ c.Expect(queueName, Equals, "myqueue")
444
+ c.Expect(message.json(), Equals, msg1.json())
445
+
446
+ c.Expect(len(queue.Inflight()), Equals, 0)
447
+ })
448
+
449
+ c.Specify("doesn't pull from inflight message set if inflight is disabled", func() {
450
+ msg1, _ := NewMsg(map[string]string{"name": "mymessage1"})
451
+ msg2, _ := NewMsg(map[string]string{"name": "mymessage2"})
452
+
453
+ conn.Deliver(msg1)
454
+ conn.Deliver(msg2)
455
+
456
+ queueName, message := queue.Pull(-1)
457
+ c.Expect(queueName, Equals, "myqueue")
458
+ c.Expect(message.json(), Equals, msg1.json())
459
+
460
+ queueName, message = queue.Pull(-1)
461
+ c.Expect(queueName, Equals, "myqueue")
462
+ c.Expect(message.json(), Equals, msg2.json())
463
+ })
464
+
465
+ c.Specify("pulls from facets of the queue in round-robin", func() {
466
+ r := config.Pool.Get()
467
+ defer r.Close()
468
+
469
+ config.Facet = func(msg *Msg) string {
470
+ str, _ := msg.Get("facet").String()
471
+ return str
472
+ }
473
+
474
+ msg1, _ := NewMsg(map[string]string{"facet": "1", "name": "my message1"})
475
+ msg2, _ := NewMsg(map[string]string{"facet": "1", "name": "my message2"})
476
+ msg3, _ := NewMsg(map[string]string{"facet": "2", "name": "my message3"})
477
+
478
+ active, _ := redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
479
+ c.Expect(len(active), Equals, 0)
480
+
481
+ conn.Deliver(msg1)
482
+ conn.Deliver(msg2)
483
+
484
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
485
+ c.Expect(len(active), Equals, 1)
486
+ c.Expect(active[0], Equals, "1")
487
+
488
+ conn.Deliver(msg3)
489
+
490
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
491
+ c.Expect(len(active), Equals, 2)
492
+ c.Expect(active[0], Equals, "1")
493
+ c.Expect(active[1], Equals, "2")
494
+
495
+ _, message := queue.Pull(-1)
496
+ c.Expect(message.json(), Equals, msg1.json())
497
+
498
+ _, message = queue.Pull(-1)
499
+ c.Expect(message.json(), Equals, msg3.json())
500
+
501
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
502
+ c.Expect(len(active), Equals, 1)
503
+ c.Expect(active[0], Equals, "1")
504
+
505
+ _, message = queue.Pull(-1)
506
+ c.Expect(message.json(), Equals, msg2.json())
507
+
508
+ active, _ = redis.Strings(r.Do("smembers", "fairway:myqueue:active_facets"))
509
+ c.Expect(len(active), Equals, 0)
510
+
511
+ _, message = queue.Pull(2)
512
+ c.Expect(message, IsNil)
55
513
  })
56
514
 
57
515
  c.Specify("removes facet from active list if it becomes empty", func() {
@@ -64,7 +522,7 @@ func QueueSpec(c gospec.Context) {
64
522
  count, _ := redis.Int(r.Do("scard", "fairway:myqueue:active_facets"))
65
523
  c.Expect(count, Equals, 1)
66
524
 
67
- queue.Pull()
525
+ queue.Pull(-1)
68
526
 
69
527
  count, _ = redis.Int(r.Do("scard", "fairway:myqueue:active_facets"))
70
528
  c.Expect(count, Equals, 0)
@@ -74,9 +532,9 @@ func QueueSpec(c gospec.Context) {
74
532
  msg, _ := NewMsg(map[string]string{})
75
533
  conn.Deliver(msg)
76
534
 
77
- queueName, message := queue.Pull()
535
+ queueName, message := queue.Pull(-1)
78
536
  c.Expect(queueName, Equals, "myqueue")
79
- queueName, message = queue.Pull()
537
+ queueName, message = queue.Pull(-1)
80
538
  c.Expect(queueName, Equals, "")
81
539
  c.Expect(message, IsNil)
82
540
  })
data/go/scripts.go CHANGED
@@ -1,8 +1,10 @@
1
1
  package fairway
2
2
 
3
3
  import (
4
- "fmt"
5
4
  "github.com/customerio/redigo/redis"
5
+
6
+ "fmt"
7
+ "time"
6
8
  )
7
9
 
8
10
  type scripts struct {
@@ -56,13 +58,30 @@ func (s *scripts) deliver(channel, facet string, msg *Msg) error {
56
58
  return err
57
59
  }
58
60
 
59
- func (s *scripts) pull(queueName string) (string, *Msg) {
61
+ func (s *scripts) deliverBytes(channel, facet string, msg []byte) error {
60
62
  conn := s.config.Pool.Get()
61
63
  defer conn.Close()
62
64
 
63
- script := s.findScript(FairwayPull, 1)
65
+ script := s.findScript(FairwayDeliver, 1)
66
+
67
+ _, err := script.Do(conn, s.namespace(), channel, facet, string(msg))
64
68
 
65
- result, err := redis.Strings(script.Do(conn, s.namespace(), queueName))
69
+ return err
70
+ }
71
+
72
+ func (s *scripts) length(queue string) (int, error) {
73
+ conn := s.config.Pool.Get()
74
+ defer conn.Close()
75
+ return redis.Int(conn.Do("get", s.namespace()+queue+":length"))
76
+ }
77
+
78
+ func (s *scripts) pull(queueName string, wait int) (string, *Msg) {
79
+ conn := s.config.Pool.Get()
80
+ defer conn.Close()
81
+
82
+ script := s.findScript(FairwayPull, 3)
83
+
84
+ result, err := redis.Strings(script.Do(conn, s.namespace(), int(time.Now().Unix()), wait, queueName))
66
85
 
67
86
  if err != nil {
68
87
  return "", nil
@@ -74,6 +93,65 @@ func (s *scripts) pull(queueName string) (string, *Msg) {
74
93
  return queue, message
75
94
  }
76
95
 
96
+ func (s *scripts) inflight(queueName string) []string {
97
+ conn := s.config.Pool.Get()
98
+ defer conn.Close()
99
+
100
+ script := s.findScript(FairwayInflight, 1)
101
+
102
+ result, err := redis.Strings(script.Do(conn, s.namespace(), queueName))
103
+
104
+ if err != nil {
105
+ return []string{}
106
+ }
107
+
108
+ return result
109
+ }
110
+
111
+ func (s *scripts) inflightLimit(queue string) (limit int, err error) {
112
+ conn := s.config.Pool.Get()
113
+ defer conn.Close()
114
+
115
+ limit, err = redis.Int(conn.Do("get", s.namespace()+queue+":limit"))
116
+
117
+ if err != nil && err.Error() == "redigo: nil returned" {
118
+ return 0, nil
119
+ }
120
+
121
+ return
122
+ }
123
+
124
+ func (s *scripts) setInflightLimit(queue string, limit int) (err error) {
125
+ conn := s.config.Pool.Get()
126
+ defer conn.Close()
127
+
128
+ _, err = conn.Do("set", s.namespace()+queue+":limit", limit)
129
+
130
+ return
131
+ }
132
+
133
+ func (s *scripts) ping(queueName string, message *Msg, wait int) error {
134
+ conn := s.config.Pool.Get()
135
+ defer conn.Close()
136
+
137
+ script := s.findScript(FairwayPing, 3)
138
+
139
+ _, err := redis.Strings(script.Do(conn, s.namespace(), int(time.Now().Unix()), wait, queueName, message.Original))
140
+
141
+ return err
142
+ }
143
+
144
+ func (s *scripts) ack(queueName string, facet string, message *Msg) error {
145
+ conn := s.config.Pool.Get()
146
+ defer conn.Close()
147
+
148
+ script := s.findScript(FairwayAck, 1)
149
+
150
+ _, err := redis.Strings(script.Do(conn, s.namespace(), queueName, facet, message.Original))
151
+
152
+ return err
153
+ }
154
+
77
155
  func (s *scripts) findScript(script func() string, keyCount int) *redis.Script {
78
156
  content := script()
79
157
 
data/lib/fairway/queue.rb CHANGED
@@ -29,12 +29,24 @@ module Fairway
29
29
  end.sum
30
30
  end
31
31
 
32
+ def inflight_limit=(limit)
33
+ redis.with_each do |conn|
34
+ unique_queues.each do |queue|
35
+ if limit < 1
36
+ conn.del("#{queue}:limit")
37
+ else
38
+ conn.set("#{queue}:limit", limit)
39
+ end
40
+ end
41
+ end
42
+ end
43
+
32
44
  def peek
33
45
  scripts.fairway_peek(@queue_names.shuffle.uniq)
34
46
  end
35
47
 
36
48
  def pull
37
- scripts.fairway_pull(@queue_names.shuffle.uniq)
49
+ scripts.fairway_pull(Time.now.to_i, -1, @queue_names.shuffle.uniq)
38
50
  end
39
51
 
40
52
  def ==(other)
@@ -32,6 +32,26 @@ module Fairway
32
32
  end
33
33
  end
34
34
 
35
+ def fairway_pull(timestamp, wait, queue_name)
36
+ loaded = false
37
+
38
+ first_pool do |conn|
39
+ conn.evalsha(script_sha(:fairway_pull), [namespace, timestamp, wait], [queue_name])
40
+ end
41
+
42
+ rescue Redis::CommandError => ex
43
+ if ex.message.include?("NOSCRIPT") && !loaded
44
+ redis.with_each do |conn|
45
+ conn.script(:load, script_source(:fairway_pull))
46
+ end
47
+
48
+ loaded = true
49
+ retry
50
+ else
51
+ raise
52
+ end
53
+ end
54
+
35
55
  def method_missing(method_name, *args)
36
56
  loaded = false
37
57
 
@@ -1,3 +1,3 @@
1
1
  module Fairway
2
- VERSION = "0.2.7"
2
+ VERSION = "0.3.1"
3
3
  end