queue_classic 2.2.0 → 2.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3137935dc373e4d8af179e93422961d1a5c07e89
4
+ data.tar.gz: 709e4565ef2dcf4635094391558942c02c44e113
5
+ SHA512:
6
+ metadata.gz: 0141f28277f3f8e26422c77c0787f3cbc84986504a97a762a62119a0036237feea1fc43ee7cc081e2483737d524aa3576d553a1a8601bf15688cf11fc0576f81
7
+ data.tar.gz: 4abb6f06e3ab1e7ad39e410cea0ff277a4b0948faf923797cec4e193131f1c54d69b36a90fba06c43b9ef6f0ed1f69ad7a9acde266c48f3566fe3a72f9e05ed1
@@ -0,0 +1,22 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+ require 'active_record'
4
+
5
+ module QC
6
+ class InstallGenerator < Rails::Generators::Base
7
+ include Rails::Generators::Migration
8
+
9
+ namespace "queue_classic:install"
10
+ self.source_paths << File.join(File.dirname(__FILE__), 'templates')
11
+ desc 'Generates (but does not run) a migration to add a queue_classic table.'
12
+
13
+ def self.next_migration_number(dirname)
14
+ next_migration_number = current_migration_number(dirname) + 1
15
+ ActiveRecord::Migration.next_migration_number(next_migration_number)
16
+ end
17
+
18
+ def create_migration_file
19
+ migration_template 'add_queue_classic.rb', 'db/migrate/add_queue_classic.rb'
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ class AddQueueClassic < ActiveRecord::Migration
2
+ def self.up
3
+ QC::Setup.create
4
+ end
5
+
6
+ def self.down
7
+ QC::Setup.drop
8
+ end
9
+ end
data/lib/queue_classic.rb CHANGED
@@ -1,24 +1,12 @@
1
- require "pg"
2
- require "uri"
3
- require "json"
4
-
5
- require "queue_classic/conn"
6
- require "queue_classic/queries"
7
- require "queue_classic/queue"
8
- require "queue_classic/worker"
9
- require "queue_classic/setup"
10
-
11
1
  module QC
12
- Root = File.expand_path("..", File.dirname(__FILE__))
13
- SqlFunctions = File.join(QC::Root, "/sql/ddl.sql")
14
- DropSqlFunctions = File.join(QC::Root, "/sql/drop_ddl.sql")
15
- CreateTable = File.join(QC::Root, "/sql/create_table.sql")
16
-
17
2
  # You can use the APP_NAME to query for
18
3
  # postgres related process information in the
19
4
  # pg_stat_activity table.
20
5
  APP_NAME = ENV["QC_APP_NAME"] || "queue_classic"
21
6
 
7
+ # Number of seconds to block on the listen chanel for new jobs.
8
+ WAIT_TIME = (ENV["QC_LISTEN_TIME"] || 5).to_i
9
+
22
10
  # Why do you want to change the table name?
23
11
  # Just deal with the default OK?
24
12
  # If you do want to change this, you will
@@ -35,11 +23,6 @@ module QC
35
23
  # There is nothing special about 9....
36
24
  TOP_BOUND = (ENV["QC_TOP_BOUND"] || 9).to_i
37
25
 
38
- # If you are using PostgreSQL > 9
39
- # then you will have access to listen/notify with payload.
40
- # Set this value if you wish to make your worker more efficient.
41
- LISTENING_WORKER = !ENV["QC_LISTENING_WORKER"].nil?
42
-
43
26
  # Set this variable if you wish for
44
27
  # the worker to fork a UNIX process for
45
28
  # each locked job. Remember to re-establish
@@ -47,11 +30,6 @@ module QC
47
30
  # for more details.
48
31
  FORK_WORKER = !ENV["QC_FORK_WORKER"].nil?
49
32
 
50
- # The worker uses an exponential back-off
51
- # algorithm to lock a job. This value will be used
52
- # as the max exponent.
53
- MAX_LOCK_ATTEMPTS = (ENV["QC_MAX_LOCK_ATTEMPTS"] || 5).to_i
54
-
55
33
  # Defer method calls on the QC module to the
56
34
  # default queue. This facilitates QC.enqueue()
57
35
  def self.method_missing(sym, *args, &block)
@@ -101,3 +79,8 @@ module QC
101
79
  return result
102
80
  end
103
81
  end
82
+
83
+ require "queue_classic/queue"
84
+ require "queue_classic/worker"
85
+ require "queue_classic/setup"
86
+ require "queue_classic/railtie" if defined?(Rails)
@@ -1,4 +1,6 @@
1
1
  require 'thread'
2
+ require 'uri'
3
+ require 'pg'
2
4
 
3
5
  module QC
4
6
  module Conn
@@ -22,15 +24,10 @@ module QC
22
24
  end
23
25
  end
24
26
 
25
- def notify(chan)
26
- log(:at => "NOTIFY")
27
- execute('NOTIFY "' + chan + '"') #quotes matter
28
- end
29
-
30
- def wait(chan, t)
31
- listen(chan)
32
- wait_for_notify(t)
33
- unlisten(chan)
27
+ def wait(chan)
28
+ execute('LISTEN "' + chan + '"')
29
+ wait_for_notify(WAIT_TIME)
30
+ execute('UNLISTEN "' + chan + '"')
34
31
  drain_notify
35
32
  end
36
33
 
@@ -106,19 +103,9 @@ module QC
106
103
  QC.log(msg)
107
104
  end
108
105
 
109
- def listen(chan)
110
- log(:at => "LISTEN")
111
- execute('LISTEN "' + chan + '"') #quotes matter
112
- end
113
-
114
- def unlisten(chan)
115
- log(:at => "UNLISTEN")
116
- execute('UNLISTEN "' + chan + '"') #quotes matter
117
- end
118
-
119
106
  def wait_for_notify(t)
120
- connection.wait_for_notify(t) do |event, pid, msg|
121
- log(:at => "received_notification")
107
+ Array.new.tap do |msgs|
108
+ connection.wait_for_notify(t) {|event, pid, msg| msgs << msg}
122
109
  end
123
110
  end
124
111
 
@@ -1,30 +1,53 @@
1
+ require 'queue_classic'
2
+ require 'queue_classic/conn'
3
+ require 'json'
4
+
1
5
  module QC
2
6
  class Queue
3
7
 
4
- attr_reader :name, :chan
5
- def initialize(name, notify=QC::LISTENING_WORKER)
8
+ attr_reader :name, :top_bound
9
+ def initialize(name, top_bound=nil)
6
10
  @name = name
7
- @chan = @name if notify
11
+ @top_bound = top_bound || QC::TOP_BOUND
8
12
  end
9
13
 
10
14
  def enqueue(method, *args)
11
- Queries.insert(name, method, args, chan)
15
+ QC.log_yield(:measure => 'queue.enqueue') do
16
+ s="INSERT INTO #{TABLE_NAME} (q_name, method, args) VALUES ($1, $2, $3)"
17
+ res = Conn.execute(s, name, method, JSON.dump(args))
18
+ end
12
19
  end
13
20
 
14
- def lock(top_bound=TOP_BOUND)
15
- Queries.lock_head(name, top_bound)
21
+ def lock
22
+ QC.log_yield(:measure => 'queue.lock') do
23
+ s = "SELECT * FROM lock_head($1, $2)"
24
+ if r = Conn.execute(s, name, top_bound)
25
+ {:id => r["id"],
26
+ :method => r["method"],
27
+ :args => JSON.parse(r["args"])}
28
+ end
29
+ end
16
30
  end
17
31
 
18
32
  def delete(id)
19
- Queries.delete(id)
33
+ QC.log_yield(:measure => 'queue.delete') do
34
+ Conn.execute("DELETE FROM #{TABLE_NAME} where id = $1", id)
35
+ end
20
36
  end
21
37
 
22
38
  def delete_all
23
- Queries.delete_all(name)
39
+ QC.log_yield(:measure => 'queue.delete_all') do
40
+ s = "DELETE FROM #{TABLE_NAME} WHERE q_name = $1"
41
+ Conn.execute(s, name)
42
+ end
24
43
  end
25
44
 
26
45
  def count
27
- Queries.count(name)
46
+ QC.log_yield(:measure => 'queue.count') do
47
+ s = "SELECT COUNT(*) FROM #{TABLE_NAME} WHERE q_name = $1"
48
+ r = Conn.execute(s, name)
49
+ r["count"].to_i
50
+ end
28
51
  end
29
52
 
30
53
  end
@@ -0,0 +1,9 @@
1
+ require 'rails/railtie'
2
+
3
+ module QC
4
+ class Railtie < ::Rails::Railtie
5
+ rake_tasks do
6
+ load 'queue_classic/tasks.rb'
7
+ end
8
+ end
9
+ end
@@ -1,40 +1,18 @@
1
1
  module QC
2
2
  module Setup
3
- extend self
3
+ Root = File.expand_path("../..", File.dirname(__FILE__))
4
+ SqlFunctions = File.join(Root, "/sql/ddl.sql")
5
+ CreateTable = File.join(Root, "/sql/create_table.sql")
6
+ DropSqlFunctions = File.join(Root, "/sql/drop_ddl.sql")
4
7
 
5
- def create
6
- create_table
7
- create_functions
8
+ def self.create
9
+ Conn.execute(File.read(CreateTable))
10
+ Conn.execute(File.read(SqlFunctions))
8
11
  end
9
12
 
10
- def drop
11
- drop_functions
12
- drop_table
13
+ def self.drop
14
+ Conn.execute("DROP TABLE IF EXISTS queue_classic_jobs CASCADE")
15
+ Conn.execute(File.read(DropSqlFunctions))
13
16
  end
14
-
15
- def create_table
16
- Conn.transaction do
17
- Conn.execute(File.read(CreateTable))
18
- end
19
- end
20
-
21
- def drop_table
22
- Conn.transaction do
23
- Conn.execute("DROP TABLE IF EXISTS queue_classic_jobs")
24
- end
25
- end
26
-
27
- def create_functions
28
- Conn.transaction do
29
- Conn.execute(File.read(SqlFunctions))
30
- end
31
- end
32
-
33
- def drop_functions
34
- Conn.transaction do
35
- Conn.execute(File.read(DropSqlFunctions))
36
- end
37
- end
38
-
39
17
  end
40
18
  end
@@ -1,3 +1,7 @@
1
+ require 'queue_classic'
2
+ require 'queue_classic/queue'
3
+ require 'queue_classic/conn'
4
+
1
5
  module QC
2
6
  class Worker
3
7
 
@@ -5,15 +9,10 @@ module QC
5
9
  # In the case no arguments are passed to the initializer,
6
10
  # the defaults are pulled from the environment variables.
7
11
  def initialize(args={})
8
- @q_name = args[:q_name] ||= QC::QUEUE
9
- @top_bound = args[:top_bound] ||= QC::TOP_BOUND
10
- @fork_worker = args[:fork_worker] ||= QC::FORK_WORKER
11
- @listening_worker = args[:listening_worker] ||= QC::LISTENING_WORKER
12
- @max_attempts = args[:max_attempts] ||= QC::MAX_LOCK_ATTEMPTS
13
-
14
- @running = true
15
- @queue = Queue.new(@q_name, @listening_worker)
12
+ @fork_worker = args[:fork_worker] || QC::FORK_WORKER
13
+ @queue = QC::Queue.new((args[:q_name] || QC::QUEUE), args[:top_bound])
16
14
  log(args.merge(:at => "worker_initialized"))
15
+ @running = true
17
16
  end
18
17
 
19
18
  # Start a loop and work jobs indefinitely.
@@ -36,9 +35,9 @@ module QC
36
35
  # Define setup_child to hook into the forking process.
37
36
  # Using setup_child is good for re-establishing database connections.
38
37
  def fork_and_work
39
- @cpid = fork {setup_child; work}
40
- log(:at => :fork, :pid => @cpid)
41
- Process.wait(@cpid)
38
+ cpid = fork {setup_child; work}
39
+ log(:at => :fork, :pid => cpid)
40
+ Process.wait(cpid)
42
41
  end
43
42
 
44
43
  # This method will lock a job & process the job.
@@ -50,33 +49,15 @@ module QC
50
49
  end
51
50
  end
52
51
 
53
- # lock_job will attempt to lock a job in the queue's table. It uses an
54
- # exponential backoff in the event that a job was not locked. This method
55
- # will return a hash when a job is obtained.
56
- #
57
- # This method will terminate early if the stop method is called or
58
- # @max_attempts has been reached.
59
- #
60
- # It is important that callers delete the job when finished.
61
- # *@queue.delete(job[:id])*
52
+ # Attempt to lock a job in the queue's table.
53
+ # Return a hash when a job is locked.
54
+ # Caller responsible for deleting the job when finished.
62
55
  def lock_job
63
56
  log(:at => "lock_job")
64
- attempts = 0
65
57
  job = nil
66
- until !@running || job
67
- job = @queue.lock(@top_bound)
68
- if job.nil?
69
- log(:at => "failed_lock", :attempts => attempts)
70
- if attempts < @max_attempts
71
- wait(2**attempts)
72
- attempts += 1
73
- next
74
- else
75
- break
76
- end
77
- else
78
- log(:at => "finished_lock", :job => job[:id])
79
- end
58
+ while @running
59
+ break if job = @queue.lock
60
+ Conn.wait(@queue.name)
80
61
  end
81
62
  job
82
63
  end
@@ -106,21 +87,6 @@ module QC
106
87
  klass.send(message, *args)
107
88
  end
108
89
 
109
- # If @listening_worker is set, the worker will use the database
110
- # to sleep. The database approach preferred over a syscall since
111
- # the database will break the sleep when new jobs are inserted into
112
- # the queue.
113
- def wait(t)
114
- if @listening_worker
115
- log(:at => "listen_wait", :wait => t)
116
- Conn.wait(@queue.chan)
117
- else
118
- log(:at => "sleep_wait", :wait => t)
119
- Kernel.sleep(t)
120
- end
121
- log(:at => "finished_listening")
122
- end
123
-
124
90
  # This method will be called when an exception
125
91
  # is raised during the execution of the job.
126
92
  def handle_failure(job,e)
data/readme.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # queue_classic
2
2
 
3
- v2.2.0
3
+ v2.2.1
4
4
 
5
5
  queue_classic provides a simple interface to a PostgreSQL-backed message queue. queue_classic specializes in concurrent locking and minimizing database load while providing a simple, intuitive developer experience. queue_classic assumes that you are already using PostgreSQL in your production environment and that adding another dependency (e.g. redis, beanstalkd, 0mq) is undesirable.
6
6
 
@@ -14,7 +14,7 @@ Features:
14
14
 
15
15
  Contents:
16
16
 
17
- * [Documentation](http://rubydoc.info/gems/queue_classic/2.2.0/frames)
17
+ * [Documentation](http://rubydoc.info/gems/queue_classic/2.2.1/frames)
18
18
  * [Usage](#usage)
19
19
  * [Setup](#setup)
20
20
  * [Configuration](#configuration)
@@ -95,7 +95,7 @@ class MyWorker < QC::Worker
95
95
  end
96
96
  end
97
97
 
98
- worker = MyWorker.new(max_attempts: 10, listening_worker: true)
98
+ worker = MyWorker.new
99
99
 
100
100
  trap('INT') {exit}
101
101
  trap('TERM') {worker.stop}
@@ -129,14 +129,7 @@ Declare dependencies in Gemfile.
129
129
 
130
130
  ```ruby
131
131
  source "http://rubygems.org"
132
- gem "queue_classic", "2.2.0"
133
- ```
134
-
135
- Require these files in your Rakefile so that you can run `rake qc:work`.
136
-
137
- ```ruby
138
- require "queue_classic"
139
- require "queue_classic/tasks"
132
+ gem "queue_classic", "2.2.1"
140
133
  ```
141
134
 
142
135
  By default, queue_classic will use the QC_DATABASE_URL falling back on DATABASE_URL. The URL must be in the following format: `postgres://username:password@localhost/database_name`. If you use Heroku's PostgreSQL service, this will already be set. If you don't want to set this variable, you can set the connection in an initializer. **QueueClassic will maintain its own connection to the database.** This may double the number of connections to your database. Set QC::Conn.connection to share the connection between Rails & QueueClassic
@@ -146,21 +139,15 @@ require 'queue_classic'
146
139
  QC::Conn.connection = ActiveRecord::Base.connection.raw_connection
147
140
  ```
148
141
 
149
- **Note on using ActiveRecord migrations:** If you use the migration, and you wish to use commands that reset the database from the stored schema (e.g. `rake db:reset`), your application must be configured with `config.active_record.schema_format = :sql` in `config/application.rb`. If you don't do this, the PL/pgSQL function that queue_classic creates will be lost when you reset the database.
142
+ Next you need to run the queue classic generator to create the database
143
+ migration. This will setup the necessary table to use queue classic.
150
144
 
151
- ```ruby
152
- require 'queue_classic'
153
-
154
- class AddQueueClassic < ActiveRecord::Migration
155
- def self.up
156
- QC::Setup.create
157
- end
158
-
159
- def self.down
160
- QC::Setup.drop
161
- end
162
- end
163
145
  ```
146
+ rails generate queue_classic:install
147
+ rake db:migrate
148
+ ```
149
+
150
+ **Note on using ActiveRecord migrations:** If you use the migration, and you wish to use commands that reset the database from the stored schema (e.g. `rake db:reset`), your application must be configured with `config.active_record.schema_format = :sql` in `config/application.rb`. If you don't do this, the PL/pgSQL function that queue_classic creates will be lost when you reset the database.
164
151
 
165
152
  ### Rake Task Setup
166
153
 
data/sql/create_table.sql CHANGED
@@ -16,4 +16,14 @@ end if;
16
16
 
17
17
  end $$ language plpgsql;
18
18
 
19
+ create function queue_classic_notify() returns trigger as $$ begin
20
+ perform pg_notify(new.q_name, '');
21
+ return null;
22
+ end $$ language plpgsql;
23
+
24
+ create trigger queue_classic_notify
25
+ after insert on queue_classic_jobs
26
+ for each row
27
+ execute procedure queue_classic_notify();
28
+
19
29
  CREATE INDEX idx_qc_on_name_only_unlocked ON queue_classic_jobs (q_name, id) WHERE locked_at IS NULL;
data/sql/drop_ddl.sql CHANGED
@@ -1,2 +1,3 @@
1
1
  DROP FUNCTION IF EXISTS lock_head(tname varchar);
2
- DROP FUNCTION IF EXISTS lock_head(q_name varchar, top_boundary integer)
2
+ DROP FUNCTION IF EXISTS lock_head(q_name varchar, top_boundary integer);
3
+ DROP FUNCTION IF EXISTS queue_classic_notify() cascade;
data/test/helper.rb CHANGED
@@ -17,36 +17,11 @@ class QCTest < Minitest::Test
17
17
  QC.delete_all
18
18
  end
19
19
 
20
- def init_db(table_name="queue_classic_jobs")
20
+ def init_db
21
21
  QC::Conn.execute("SET client_min_messages TO 'warning'")
22
22
  QC::Setup.drop
23
23
  QC::Setup.create
24
- QC::Conn.execute(<<EOS)
25
- DO $$
26
- -- Set initial sequence to a large number to test the entire toolchain
27
- -- works on integers with higher bits set.
28
- DECLARE
29
- quoted_name text;
30
- quoted_size text;
31
- BEGIN
32
- -- Find the name of the relevant sequence.
33
- --
34
- -- pg_get_serial_sequence quotes identifiers as part of its
35
- -- behavior.
36
- SELECT name
37
- INTO STRICT quoted_name
38
- FROM pg_get_serial_sequence('queue_classic_jobs', 'id') AS name;
39
-
40
- -- Don't quote, because ALTER SEQUENCE RESTART doesn't like
41
- -- general literals, only unquoted numeric literals.
42
- SELECT pow(2, 34)::text AS size
43
- INTO STRICT quoted_size;
44
-
45
- EXECUTE 'ALTER SEQUENCE ' || quoted_name ||
46
- ' RESTART ' || quoted_size || ';';
47
- END;
48
- $$;
49
- EOS
24
+ QC::Conn.execute(File.read('./test/helper.sql'))
50
25
  end
51
26
 
52
27
  def capture_debug_output
data/test/queue_test.rb CHANGED
@@ -56,7 +56,7 @@ class QueueTest < QCTest
56
56
  end
57
57
 
58
58
  def test_queue_instance
59
- queue = QC::Queue.new("queue_classic_jobs", false)
59
+ queue = QC::Queue.new("queue_classic_jobs")
60
60
  queue.enqueue("Klass.method")
61
61
  assert_equal(1, queue.count)
62
62
  queue.delete(queue.lock[:id])
@@ -64,7 +64,7 @@ class QueueTest < QCTest
64
64
  end
65
65
 
66
66
  def test_repair_after_error
67
- queue = QC::Queue.new("queue_classic_jobs", false)
67
+ queue = QC::Queue.new("queue_classic_jobs")
68
68
  queue.enqueue("Klass.method")
69
69
  assert_equal(1, queue.count)
70
70
  connection = QC::Conn.connection
@@ -100,4 +100,17 @@ class QueueTest < QCTest
100
100
  ensure
101
101
  QC.default_queue = nil
102
102
  end
103
+
104
+ def test_enqueue_triggers_notify
105
+ QC::Conn.execute('LISTEN "' + QC::QUEUE + '"')
106
+ QC::Conn.send(:drain_notify)
107
+
108
+ msgs = QC::Conn.send(:wait_for_notify, 0.25)
109
+ assert_equal(0, msgs.length)
110
+
111
+ QC.enqueue("Klass.method")
112
+ msgs = QC::Conn.send(:wait_for_notify, 0.25)
113
+ assert_equal(1, msgs.length)
114
+ end
115
+
103
116
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: queue_classic
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
5
- prerelease:
4
+ version: 2.2.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Ryan Smith (♠ ace hacker)
@@ -14,7 +13,6 @@ dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: pg
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ~>
28
25
  - !ruby/object:Gem::Version
@@ -39,9 +36,11 @@ files:
39
36
  - sql/create_table.sql
40
37
  - sql/ddl.sql
41
38
  - sql/drop_ddl.sql
39
+ - lib/generators/queue_classic/install_generator.rb
40
+ - lib/generators/queue_classic/templates/add_queue_classic.rb
42
41
  - lib/queue_classic/conn.rb
43
- - lib/queue_classic/queries.rb
44
42
  - lib/queue_classic/queue.rb
43
+ - lib/queue_classic/railtie.rb
45
44
  - lib/queue_classic/setup.rb
46
45
  - lib/queue_classic/tasks.rb
47
46
  - lib/queue_classic/worker.rb
@@ -54,27 +53,26 @@ files:
54
53
  homepage: http://github.com/ryandotsmith/queue_classic
55
54
  licenses:
56
55
  - MIT
56
+ metadata: {}
57
57
  post_install_message:
58
58
  rdoc_options: []
59
59
  require_paths:
60
60
  - lib
61
61
  required_ruby_version: !ruby/object:Gem::Requirement
62
- none: false
63
62
  requirements:
64
- - - ! '>='
63
+ - - '>='
65
64
  - !ruby/object:Gem::Version
66
65
  version: '0'
67
66
  required_rubygems_version: !ruby/object:Gem::Requirement
68
- none: false
69
67
  requirements:
70
- - - ! '>='
68
+ - - '>='
71
69
  - !ruby/object:Gem::Version
72
70
  version: '0'
73
71
  requirements: []
74
72
  rubyforge_project:
75
- rubygems_version: 1.8.23
73
+ rubygems_version: 2.0.3
76
74
  signing_key:
77
- specification_version: 3
75
+ specification_version: 4
78
76
  summary: postgres backed queue
79
77
  test_files:
80
78
  - test/benchmark_test.rb
@@ -1,42 +0,0 @@
1
- module QC
2
- module Queries
3
- extend self
4
-
5
- def insert(q_name, method, args, chan=nil)
6
- QC.log_yield(:action => "insert_job") do
7
- s = "INSERT INTO #{TABLE_NAME} (q_name, method, args) VALUES ($1, $2, $3)"
8
- res = Conn.execute(s, q_name, method, JSON.dump(args))
9
- Conn.notify(chan) if chan
10
- end
11
- end
12
-
13
- def lock_head(q_name, top_bound)
14
- s = "SELECT * FROM lock_head($1, $2)"
15
- if r = Conn.execute(s, q_name, top_bound)
16
- {
17
- :id => r["id"],
18
- :method => r["method"],
19
- :args => JSON.parse(r["args"])
20
- }
21
- end
22
- end
23
-
24
- def count(q_name=nil)
25
- s = "SELECT COUNT(*) FROM #{TABLE_NAME}"
26
- s << " WHERE q_name = $1" if q_name
27
- r = Conn.execute(*[s, q_name].compact)
28
- r["count"].to_i
29
- end
30
-
31
- def delete(id)
32
- Conn.execute("DELETE FROM #{TABLE_NAME} where id = $1", id)
33
- end
34
-
35
- def delete_all(q_name=nil)
36
- s = "DELETE FROM #{TABLE_NAME}"
37
- s << " WHERE q_name = $1" if q_name
38
- Conn.execute(*[s, q_name].compact)
39
- end
40
-
41
- end
42
- end