queue_classic 0.3.2 → 0.3.3.pre

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 CHANGED
@@ -11,6 +11,8 @@ require 'queue_classic/queue'
11
11
  require 'queue_classic/job'
12
12
 
13
13
  module QC
14
+ VERBOSE = ENV["VERBOSE"] == true
15
+
14
16
  def self.method_missing(sym, *args, &block)
15
17
  Queue.send(sym, *args, &block)
16
18
  end
@@ -2,8 +2,10 @@ module QC
2
2
  class Database
3
3
  @@connection = nil
4
4
 
5
- MAX_TOP_BOUND = 9
6
- DEFAULT_QUEUE_NAME = "queue_classic_jobs"
5
+ DATABASE_URL = (ENV["QC_DATABASE_URL"] || ENV["DATABASE_URL"])
6
+ MAX_TOP_BOUND = (ENV["QC_TOP_BOUND"] || 9).to_i
7
+ NOTIFY_TIMEOUT = (ENV["QC_NOTIFY_TIMEOUT"] || 10).to_i
8
+ DEFAULT_QUEUE_NAME = "queue_classic_jobs"
7
9
 
8
10
  def self.create_queue(name)
9
11
  db = new(name)
@@ -15,9 +17,9 @@ module QC
15
17
  attr_reader :table_name
16
18
 
17
19
  def initialize(queue_name=nil)
18
- @top_boundry = ENV["TOP_BOUND"] || MAX_TOP_BOUND
20
+ @top_boundry = MAX_TOP_BOUND
19
21
  @table_name = queue_name || DEFAULT_QUEUE_NAME
20
- @db_params = URI.parse(ENV["DATABASE_URL"])
22
+ @db_params = URI.parse(DATABASE_URL)
21
23
  end
22
24
 
23
25
  def init_db
@@ -26,6 +28,18 @@ module QC
26
28
  load_functions
27
29
  end
28
30
 
31
+ def listen
32
+ execute("LISTEN queue_classic_jobs")
33
+ end
34
+
35
+ def unlisten
36
+ execute("UNLISTEN queue_classic_jobs")
37
+ end
38
+
39
+ def wait_for_notify
40
+ connection.wait_for_notify(NOTIFY_TIMEOUT)
41
+ end
42
+
29
43
  def waiting_conns
30
44
  execute("SELECT * FROM pg_stat_activity WHERE datname = '#{@name}' AND waiting = 't' AND application_name = 'queue_classic'")
31
45
  end
@@ -58,9 +72,8 @@ module QC
58
72
  @db_params.user,
59
73
  @db_params.password
60
74
  )
61
- @@connection.exec("LISTEN queue_classic_jobs")
62
75
  @@connection.exec("SET application_name = 'queue_classic'")
63
- silence_warnings unless ENV["LOGGING_ENABLED"]
76
+ silence_warnings unless VERBOSE
64
77
  end
65
78
  @@connection
66
79
  end
@@ -8,7 +8,6 @@ module QC
8
8
 
9
9
  def <<(details)
10
10
  execute("INSERT INTO #{@table_name} (details) VALUES ('#{details.to_json}')")
11
- execute("NOTIFY queue_classic_jobs, 'new-job'")
12
11
  end
13
12
 
14
13
  def count
@@ -28,17 +27,8 @@ module QC
28
27
  find_many { "SELECT * FROM #{@table_name} WHERE details LIKE '%#{q}%'" }
29
28
  end
30
29
 
31
- def lock_head
32
- find_one { "SELECT * FROM lock_head('#{@table_name}')" }
33
- end
34
-
35
30
  def first
36
- if job = lock_head
37
- job
38
- else
39
- @database.connection.wait_for_notify(1) {|e,p,msg| job = lock_head if msg == "new-job" }
40
- job
41
- end
31
+ find_one { "SELECT * FROM lock_head('#{@table_name}')" }
42
32
  end
43
33
 
44
34
  def each
@@ -1,9 +1,12 @@
1
1
  module QC
2
2
  class Worker
3
3
 
4
+ MAX_LOCK_ATTEMPTS = (ENV["QC_MAX_LOCK_ATTEMPTS"] || 5).to_i
5
+
4
6
  def initialize
5
- @running = true
6
- @queue = QC::Queue.new(ENV["QUEUE"])
7
+ @running = true
8
+ @queue = QC::Queue.new(ENV["QUEUE"])
9
+ @fork_worker = ENV["QC_FORK_WORKER"] == "true"
7
10
  handle_signals
8
11
  end
9
12
 
@@ -11,8 +14,12 @@ module QC
11
14
  @running
12
15
  end
13
16
 
17
+ def fork_worker?
18
+ @fork_worker
19
+ end
20
+
14
21
  def handle_signals
15
- %W(INT TRAP).each do |sig|
22
+ %W(INT TERM).each do |sig|
16
23
  trap(sig) do
17
24
  if running?
18
25
  @running = false
@@ -24,13 +31,22 @@ module QC
24
31
  end
25
32
 
26
33
  def start
27
- while running? do
28
- work
34
+ while running?
35
+ if fork_worker?
36
+ fork_and_work
37
+ else
38
+ work
39
+ end
29
40
  end
30
41
  end
31
42
 
43
+ def fork_and_work
44
+ @cpid = fork { work }
45
+ Process.wait(@cpid)
46
+ end
47
+
32
48
  def work
33
- if job = @queue.dequeue #blocks until we have a job
49
+ if job = lock_job
34
50
  begin
35
51
  job.work
36
52
  rescue Object => e
@@ -39,6 +55,27 @@ module QC
39
55
  @queue.delete(job)
40
56
  end
41
57
  end
58
+ job = nil
59
+ GC.start
60
+ end
61
+
62
+ def lock_job
63
+ attempts = 0
64
+ job = nil
65
+ until job
66
+ job = @queue.dequeue
67
+ if job.nil?
68
+ attempts += 1
69
+ if attempts < MAX_LOCK_ATTEMPTS
70
+ sleep(2**attempts)
71
+ next
72
+ else
73
+ break
74
+ end
75
+ else
76
+ end
77
+ end
78
+ job
42
79
  end
43
80
 
44
81
  #override this method to do whatever you want
data/test/queue_test.rb CHANGED
@@ -53,6 +53,7 @@ context "Queue" do
53
53
  QC::Queue.length
54
54
  QC::Queue.enqueue "Klass.method"
55
55
  QC::Queue.delete QC::Queue.dequeue
56
+ QC::Queue.enqueue "Klass.method"
56
57
  QC::Queue.dequeue
57
58
  assert_equal 1, QC.connection_status[:total]
58
59
  end
metadata CHANGED
@@ -1,49 +1,47 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: queue_classic
3
- version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.3.2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.3.pre
5
+ prerelease: 6
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Ryan Smith
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-08-03 00:00:00 -07:00
14
- default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
12
+ date: 2011-08-22 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
17
15
  name: pg
18
- prerelease: false
19
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &2153629240 !ruby/object:Gem::Requirement
20
17
  none: false
21
- requirements:
22
- - - ">="
23
- - !ruby/object:Gem::Version
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
24
21
  version: 0.10.1
25
22
  type: :runtime
26
- version_requirements: *id001
27
- - !ruby/object:Gem::Dependency
28
- name: json
29
23
  prerelease: false
30
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *2153629240
25
+ - !ruby/object:Gem::Dependency
26
+ name: json
27
+ requirement: &2153628740 !ruby/object:Gem::Requirement
31
28
  none: false
32
- requirements:
33
- - - ">="
34
- - !ruby/object:Gem::Version
35
- version: "0"
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
36
33
  type: :runtime
37
- version_requirements: *id002
38
- description: Queue Classic (beta) is a queueing library for Ruby apps (Rails, Sinatra, Etc...) Queue Classic features asynchronous job polling, database maintained locks and no ridiculous dependencies. As a matter of fact, Queue Classic only requires the pg and json.
34
+ prerelease: false
35
+ version_requirements: *2153628740
36
+ description: Queue Classic (beta) is a queueing library for Ruby apps (Rails, Sinatra,
37
+ Etc...) Queue Classic features asynchronous job polling, database maintained locks
38
+ and no ridiculous dependencies. As a matter of fact, Queue Classic only requires
39
+ the pg and json.
39
40
  email: ryan@heroku.com
40
41
  executables: []
41
-
42
42
  extensions: []
43
-
44
43
  extra_rdoc_files: []
45
-
46
- files:
44
+ files:
47
45
  - readme.md
48
46
  - lib/queue_classic/database.rb
49
47
  - lib/queue_classic/durable_array.rb
@@ -58,35 +56,34 @@ files:
58
56
  - test/job_test.rb
59
57
  - test/queue_test.rb
60
58
  - test/worker_test.rb
61
- has_rdoc: true
62
59
  homepage: http://github.com/ryandotsmith/queue_classic
63
60
  licenses: []
64
-
65
61
  post_install_message:
66
62
  rdoc_options: []
67
-
68
- require_paths:
63
+ require_paths:
69
64
  - lib
70
- required_ruby_version: !ruby/object:Gem::Requirement
65
+ required_ruby_version: !ruby/object:Gem::Requirement
71
66
  none: false
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: "0"
76
- required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
72
  none: false
78
- requirements:
79
- - - ">="
80
- - !ruby/object:Gem::Version
81
- version: "0"
73
+ requirements:
74
+ - - ! '>'
75
+ - !ruby/object:Gem::Version
76
+ version: 1.3.1
82
77
  requirements: []
83
-
84
78
  rubyforge_project:
85
- rubygems_version: 1.6.2
79
+ rubygems_version: 1.8.7
86
80
  signing_key:
87
81
  specification_version: 3
88
- summary: Queue Classic (beta) is a queueing library for Ruby apps (Rails, Sinatra, Etc...) Queue Classic features asynchronous job polling, database maintained locks and no ridiculous dependencies. As a matter of fact, Queue Classic only requires the pg and json.(simple)
89
- test_files:
82
+ summary: Queue Classic (beta) is a queueing library for Ruby apps (Rails, Sinatra,
83
+ Etc...) Queue Classic features asynchronous job polling, database maintained locks
84
+ and no ridiculous dependencies. As a matter of fact, Queue Classic only requires
85
+ the pg and json.(simple)
86
+ test_files:
90
87
  - test/durable_array_test.rb
91
88
  - test/job_test.rb
92
89
  - test/queue_test.rb