queue_classic 2.0.0 → 2.0.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.
- data/lib/queue_classic.rb +0 -3
- data/lib/queue_classic/conn.rb +2 -0
- data/lib/queue_classic/okjson.rb +57 -67
- data/lib/queue_classic/queue.rb +2 -2
- data/readme.md +8 -18
- data/test/queue_test.rb +17 -0
- metadata +8 -7
data/lib/queue_classic.rb
CHANGED
@@ -12,9 +12,6 @@ require "queue_classic/worker"
|
|
12
12
|
require "queue_classic/setup"
|
13
13
|
|
14
14
|
module QC
|
15
|
-
# ENV["LOG_LEVEL"] is used in Scrolls
|
16
|
-
Scrolls::Log.start
|
17
|
-
|
18
15
|
Root = File.expand_path("..", File.dirname(__FILE__))
|
19
16
|
SqlFunctions = File.join(QC::Root, "/sql/ddl.sql")
|
20
17
|
DropSqlFunctions = File.join(QC::Root, "/sql/drop_ddl.sql")
|
data/lib/queue_classic/conn.rb
CHANGED
@@ -12,6 +12,7 @@ module QC
|
|
12
12
|
result.length > 1 ? result : result.pop
|
13
13
|
rescue PGError => e
|
14
14
|
log(:error => e.inspect)
|
15
|
+
disconnect
|
15
16
|
raise
|
16
17
|
end
|
17
18
|
end
|
@@ -64,6 +65,7 @@ module QC
|
|
64
65
|
|
65
66
|
def disconnect
|
66
67
|
connection.finish
|
68
|
+
ensure
|
67
69
|
@connection = nil
|
68
70
|
end
|
69
71
|
|
data/lib/queue_classic/okjson.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
module QC
|
2
1
|
# encoding: UTF-8
|
3
2
|
#
|
4
3
|
# Copyright 2011, 2012 Keith Rarick
|
@@ -28,6 +27,7 @@ require 'stringio'
|
|
28
27
|
# Some parts adapted from
|
29
28
|
# http://golang.org/src/pkg/json/decode.go and
|
30
29
|
# http://golang.org/src/pkg/utf8/utf8.go
|
30
|
+
module QC
|
31
31
|
module OkJson
|
32
32
|
extend self
|
33
33
|
|
@@ -220,9 +220,9 @@ module OkJson
|
|
220
220
|
end
|
221
221
|
|
222
222
|
|
223
|
-
def nulltok(s); s[0,4] == 'null'
|
224
|
-
def truetok(s); s[0,4] == 'true'
|
225
|
-
def falsetok(s); s[0,5] == 'false'
|
223
|
+
def nulltok(s); s[0,4] == 'null' ? [:val, 'null', nil] : [] end
|
224
|
+
def truetok(s); s[0,4] == 'true' ? [:val, 'true', true] : [] end
|
225
|
+
def falsetok(s); s[0,5] == 'false' ? [:val, 'false', false] : [] end
|
226
226
|
|
227
227
|
|
228
228
|
def numtok(s)
|
@@ -235,6 +235,8 @@ module OkJson
|
|
235
235
|
else
|
236
236
|
[:val, m[0], Integer(m[0])]
|
237
237
|
end
|
238
|
+
else
|
239
|
+
[]
|
238
240
|
end
|
239
241
|
end
|
240
242
|
|
@@ -375,15 +377,6 @@ module OkJson
|
|
375
377
|
end
|
376
378
|
|
377
379
|
|
378
|
-
def unsubst(u)
|
379
|
-
if u < Usurrself || u > Umax || surrogate?(u)
|
380
|
-
return Ucharerr, Ucharerr
|
381
|
-
end
|
382
|
-
u -= Usurrself
|
383
|
-
[Usurr1 + ((u>>10)&0x3ff), Usurr2 + (u&0x3ff)]
|
384
|
-
end
|
385
|
-
|
386
|
-
|
387
380
|
def surrogate?(u)
|
388
381
|
Usurr1 <= u && u < Usurr3
|
389
382
|
end
|
@@ -473,15 +466,18 @@ module OkJson
|
|
473
466
|
else
|
474
467
|
c = s[r]
|
475
468
|
case true
|
469
|
+
when rubydoesenc
|
470
|
+
begin
|
471
|
+
c.ord # will raise an error if c is invalid UTF-8
|
472
|
+
t.write(c)
|
473
|
+
rescue
|
474
|
+
t.write(Ustrerr)
|
475
|
+
end
|
476
476
|
when Spc <= c && c <= ?~
|
477
477
|
t.putc(c)
|
478
|
-
when rubydoesenc
|
479
|
-
u = c.ord
|
480
|
-
surrenc(t, u)
|
481
478
|
else
|
482
|
-
|
483
|
-
r +=
|
484
|
-
surrenc(t, u)
|
479
|
+
n = ucharcopy(t, s, r) # ensure valid UTF-8 output
|
480
|
+
r += n - 1 # r is incremented below
|
485
481
|
end
|
486
482
|
end
|
487
483
|
r += 1
|
@@ -491,28 +487,6 @@ module OkJson
|
|
491
487
|
end
|
492
488
|
|
493
489
|
|
494
|
-
def surrenc(t, u)
|
495
|
-
if u < 0x10000
|
496
|
-
t.print('\\u')
|
497
|
-
hexenc4(t, u)
|
498
|
-
else
|
499
|
-
u1, u2 = unsubst(u)
|
500
|
-
t.print('\\u')
|
501
|
-
hexenc4(t, u1)
|
502
|
-
t.print('\\u')
|
503
|
-
hexenc4(t, u2)
|
504
|
-
end
|
505
|
-
end
|
506
|
-
|
507
|
-
|
508
|
-
def hexenc4(t, u)
|
509
|
-
t.putc(Hex[(u>>12)&0xf])
|
510
|
-
t.putc(Hex[(u>>8)&0xf])
|
511
|
-
t.putc(Hex[(u>>4)&0xf])
|
512
|
-
t.putc(Hex[u&0xf])
|
513
|
-
end
|
514
|
-
|
515
|
-
|
516
490
|
def numenc(x)
|
517
491
|
if ((x.nan? || x.infinite?) rescue false)
|
518
492
|
raise Error, "Numeric cannot be represented: #{x}"
|
@@ -521,60 +495,77 @@ module OkJson
|
|
521
495
|
end
|
522
496
|
|
523
497
|
|
524
|
-
#
|
525
|
-
#
|
526
|
-
#
|
527
|
-
|
498
|
+
# Copies the valid UTF-8 bytes of a single character
|
499
|
+
# from string s at position i to I/O object t, and
|
500
|
+
# returns the number of bytes copied.
|
501
|
+
# If no valid UTF-8 char exists at position i,
|
502
|
+
# ucharcopy writes Ustrerr and returns 1.
|
503
|
+
def ucharcopy(t, s, i)
|
528
504
|
n = s.length - i
|
529
|
-
|
505
|
+
raise Utf8Error if n < 1
|
530
506
|
|
531
507
|
c0 = s[i].ord
|
532
508
|
|
533
509
|
# 1-byte, 7-bit sequence?
|
534
510
|
if c0 < Utagx
|
535
|
-
|
511
|
+
t.putc(c0)
|
512
|
+
return 1
|
536
513
|
end
|
537
514
|
|
538
|
-
# unexpected continuation byte?
|
539
|
-
return [Ucharerr, 1] if c0 < Utag2
|
515
|
+
raise Utf8Error if c0 < Utag2 # unexpected continuation byte?
|
540
516
|
|
541
|
-
# need continuation byte
|
542
|
-
return [Ucharerr, 1] if n < 2
|
517
|
+
raise Utf8Error if n < 2 # need continuation byte
|
543
518
|
c1 = s[i+1].ord
|
544
|
-
|
519
|
+
raise Utf8Error if c1 < Utagx || Utag2 <= c1
|
545
520
|
|
546
521
|
# 2-byte, 11-bit sequence?
|
547
522
|
if c0 < Utag3
|
548
|
-
|
549
|
-
|
550
|
-
|
523
|
+
raise Utf8Error if ((c0&Umask2)<<6 | (c1&Umaskx)) <= Uchar1max
|
524
|
+
t.putc(c0)
|
525
|
+
t.putc(c1)
|
526
|
+
return 2
|
551
527
|
end
|
552
528
|
|
553
529
|
# need second continuation byte
|
554
|
-
|
530
|
+
raise Utf8Error if n < 3
|
531
|
+
|
555
532
|
c2 = s[i+2].ord
|
556
|
-
|
533
|
+
raise Utf8Error if c2 < Utagx || Utag2 <= c2
|
557
534
|
|
558
535
|
# 3-byte, 16-bit sequence?
|
559
536
|
if c0 < Utag4
|
560
537
|
u = (c0&Umask3)<<12 | (c1&Umaskx)<<6 | (c2&Umaskx)
|
561
|
-
|
562
|
-
|
538
|
+
raise Utf8Error if u <= Uchar2max
|
539
|
+
t.putc(c0)
|
540
|
+
t.putc(c1)
|
541
|
+
t.putc(c2)
|
542
|
+
return 3
|
563
543
|
end
|
564
544
|
|
565
545
|
# need third continuation byte
|
566
|
-
|
546
|
+
raise Utf8Error if n < 4
|
567
547
|
c3 = s[i+3].ord
|
568
|
-
|
548
|
+
raise Utf8Error if c3 < Utagx || Utag2 <= c3
|
569
549
|
|
570
550
|
# 4-byte, 21-bit sequence?
|
571
551
|
if c0 < Utag5
|
572
552
|
u = (c0&Umask4)<<18 | (c1&Umaskx)<<12 | (c2&Umaskx)<<6 | (c3&Umaskx)
|
573
|
-
|
574
|
-
|
575
|
-
|
553
|
+
raise Utf8Error if u <= Uchar3max
|
554
|
+
t.putc(c0)
|
555
|
+
t.putc(c1)
|
556
|
+
t.putc(c2)
|
557
|
+
t.putc(c3)
|
558
|
+
return 4
|
559
|
+
end
|
560
|
+
|
561
|
+
raise Utf8Error
|
562
|
+
rescue Utf8Error
|
563
|
+
t.write(Ustrerr)
|
564
|
+
return 1
|
565
|
+
end
|
566
|
+
|
576
567
|
|
577
|
-
|
568
|
+
class Utf8Error < ::StandardError
|
578
569
|
end
|
579
570
|
|
580
571
|
|
@@ -595,14 +586,13 @@ module OkJson
|
|
595
586
|
Uchar2max = (1<<11) - 1
|
596
587
|
Uchar3max = (1<<16) - 1
|
597
588
|
Ucharerr = 0xFFFD # unicode "replacement char"
|
589
|
+
Ustrerr = "\xef\xbf\xbd" # unicode "replacement char"
|
598
590
|
Usurrself = 0x10000
|
599
591
|
Usurr1 = 0xd800
|
600
592
|
Usurr2 = 0xdc00
|
601
593
|
Usurr3 = 0xe000
|
602
|
-
Umax = 0x10ffff
|
603
594
|
|
604
595
|
Spc = ' '[0]
|
605
596
|
Unesc = {?b=>?\b, ?f=>?\f, ?n=>?\n, ?r=>?\r, ?t=>?\t}
|
606
|
-
Hex = '0123456789abcdef'
|
607
597
|
end
|
608
598
|
end
|
data/lib/queue_classic/queue.rb
CHANGED
data/readme.md
CHANGED
@@ -135,7 +135,7 @@ end
|
|
135
135
|
## Configure
|
136
136
|
|
137
137
|
All configuration takes place in the form of environment vars.
|
138
|
-
See [queue_classic.rb](https://github.com/ryandotsmith/queue_classic/blob/master/lib/queue_classic.rb#
|
138
|
+
See [queue_classic.rb](https://github.com/ryandotsmith/queue_classic/blob/master/lib/queue_classic.rb#L23-62)
|
139
139
|
for a list of options.
|
140
140
|
|
141
141
|
## Usage
|
@@ -262,7 +262,7 @@ require "queue_classic"
|
|
262
262
|
QC::Worker.new.start
|
263
263
|
```
|
264
264
|
|
265
|
-
####
|
265
|
+
#### Subclass QC::Worker
|
266
266
|
|
267
267
|
Now that we have seen how to run a worker process, let's take a look at how to customize a worker.
|
268
268
|
The class `QC::Worker` will probably suit most of your needs; however, there are some mechanisms
|
@@ -278,7 +278,7 @@ class MyWorker < QC::Worker
|
|
278
278
|
|
279
279
|
# retry the job
|
280
280
|
def handle_failure(job, exception)
|
281
|
-
@queue.enqueue(job[:method], job[:args])
|
281
|
+
@queue.enqueue(job[:method], *job[:args])
|
282
282
|
end
|
283
283
|
|
284
284
|
# the forked proc needs a new db connection
|
@@ -444,24 +444,10 @@ database.
|
|
444
444
|
|
445
445
|
To achieve this we will create a helper method:
|
446
446
|
|
447
|
-
```ruby
|
448
|
-
|
449
|
-
def qc_txn
|
450
|
-
begin
|
451
|
-
QC.database.execute("BEGIN")
|
452
|
-
yield
|
453
|
-
QC.database.execute("COMMIT")
|
454
|
-
rescue Exception
|
455
|
-
QC.database.execute("ROLLBACK")
|
456
|
-
raise
|
457
|
-
end
|
458
|
-
end
|
459
|
-
```
|
460
|
-
|
461
447
|
Now in your application code you can do something like:
|
462
448
|
|
463
449
|
```ruby
|
464
|
-
|
450
|
+
QC::Conn.transaction do
|
465
451
|
Account.all.each do |act|
|
466
452
|
QC.enqueue("Emailer.send_notice", act.id)
|
467
453
|
end
|
@@ -579,3 +565,7 @@ $ createdb queue_classic_test
|
|
579
565
|
$ export QC_DATABASE_URL="postgres://username:pass@localhost/queue_classic_test"
|
580
566
|
$ rake
|
581
567
|
```
|
568
|
+
|
569
|
+
### License
|
570
|
+
|
571
|
+
queue_classic is released under the MIT License (http://www.opensource.org/licenses/mit-license.php).
|
data/test/queue_test.rb
CHANGED
@@ -56,4 +56,21 @@ class QueueTest < QCTest
|
|
56
56
|
assert_equal(0, queue.count)
|
57
57
|
end
|
58
58
|
|
59
|
+
def test_repair_after_error
|
60
|
+
queue = QC::Queue.new("queue_classic_jobs", false)
|
61
|
+
queue.enqueue("Klass.method")
|
62
|
+
assert_equal(1, queue.count)
|
63
|
+
connection = QC::Conn.connection
|
64
|
+
saved_method = connection.method(:exec)
|
65
|
+
def connection.exec(*args)
|
66
|
+
raise PGError
|
67
|
+
end
|
68
|
+
assert_raises(PG::Error) { queue.enqueue("Klass.other_method") }
|
69
|
+
assert_equal(1, queue.count)
|
70
|
+
queue.enqueue("Klass.other_method")
|
71
|
+
assert_equal(2, queue.count)
|
72
|
+
rescue PG::Error
|
73
|
+
QC::Conn.disconnect
|
74
|
+
assert false, "Expected to QC repair after connection error"
|
75
|
+
end
|
59
76
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: queue_classic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-07-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: pg
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.
|
21
|
+
version: 0.14.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 0.
|
29
|
+
version: 0.14.0
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: scrolls
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -34,7 +34,7 @@ dependencies:
|
|
34
34
|
requirements:
|
35
35
|
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: 0.
|
37
|
+
version: 0.2.1
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: 0.
|
45
|
+
version: 0.2.1
|
46
46
|
description: queue_classic is a queueing library for Ruby apps. (Rails, Sinatra, Etc...)
|
47
47
|
queue_classic features asynchronous job polling, database maintained locks and no
|
48
48
|
ridiculous dependencies. As a matter of fact, queue_classic only requires pg.
|
@@ -67,7 +67,8 @@ files:
|
|
67
67
|
- test/queue_test.rb
|
68
68
|
- test/worker_test.rb
|
69
69
|
homepage: http://github.com/ryandotsmith/queue_classic
|
70
|
-
licenses:
|
70
|
+
licenses:
|
71
|
+
- MIT
|
71
72
|
post_install_message:
|
72
73
|
rdoc_options: []
|
73
74
|
require_paths:
|