queue_classic 3.0.3 → 3.1.0.RC1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cfade5886b2c70ee4702e8237fd27593f19d752f
4
- data.tar.gz: 01102c720913864a3ff4199fe3bd5f85d33ce542
3
+ metadata.gz: 4280312436762af6532d5ba73b94063e2f3fdfcf
4
+ data.tar.gz: 8ad63234d7e013a19238e6fbf1722c9eb688af8b
5
5
  SHA512:
6
- metadata.gz: 93d1dff4a3d75befa7f9d7a4aa89bdee0ee6b6584c434592c01ccf9bbdbed17d91b4906caa13acff26fb302ce02ff8c144cbd2d9897381cc1217b697a73a2db6
7
- data.tar.gz: 50c35143f017995c4e9665dd36f8f48b1d796cf26139bc99168e559061ebdb686b43277bee92dc286b3c88256e606cebec191f16bc346c997ece5241eaf2373c
6
+ metadata.gz: 6b528e1cb1e85ec03e7ccecd36e20394bd578d6e912a8ae531c253ef0ad0c2e996dcb5a53be56650af09c117be67410e3562dcfd37f067b323fb0584c0b6f841
7
+ data.tar.gz: 02f999edfa7d92a9286b31970e1ef999dc0a37e0355b6f3bd50454b790c154295cfb0db541d9274f3f624486d305c31bbc19db49deb8d026fd69bdf9fcf24603
@@ -27,6 +27,10 @@ module QC
27
27
  if self.class.migration_exists?('db/migrate', 'update_queue_classic_3_0_2').nil?
28
28
  migration_template 'update_queue_classic_3_0_2.rb', 'db/migrate/update_queue_classic_3_0_2.rb'
29
29
  end
30
+
31
+ if self.class.migration_exists?('db/migrate', 'update_queue_classic_3_1_0').nil?
32
+ migration_template 'update_queue_classic_3_1_0.rb', 'db/migrate/update_queue_classic_3_1_0.rb'
33
+ end
30
34
  end
31
35
  end
32
36
  end
@@ -0,0 +1,9 @@
1
+ class UpdateQueueClassic310 < ActiveRecord::Migration
2
+ def self.up
3
+ QC::Setup.update_to_3_1_0
4
+ end
5
+
6
+ def self.down
7
+ QC::Setup.downgrade_from_3_1_0
8
+ end
9
+ end
@@ -57,7 +57,13 @@ module QC
57
57
  end
58
58
 
59
59
  def self.default_conn_adapter
60
- @conn_adapter ||= ConnAdapter.new
60
+ return @conn_adapter if defined?(@conn_adapter) && @conn_adapter
61
+ if rails_connection_sharing_enabled?
62
+ @conn_adapter = ConnAdapter.new(ActiveRecord::Base.connection.raw_connection)
63
+ else
64
+ @conn_adapter = ConnAdapter.new
65
+ end
66
+ @conn_adapter
61
67
  end
62
68
 
63
69
  def self.default_conn_adapter=(conn)
@@ -81,7 +87,6 @@ module QC
81
87
  result = nil
82
88
  data = {:lib => "queue-classic"}.merge(data)
83
89
  if block_given?
84
- start = Time.now
85
90
  result = yield
86
91
  data.merge(:elapsed => Integer((Time.now - t0)*1000))
87
92
  end
@@ -103,6 +108,13 @@ module QC
103
108
  def self.unlock_jobs_of_dead_workers
104
109
  @conn_adapter.execute("UPDATE #{QC::TABLE_NAME} SET locked_at = NULL, locked_by = NULL WHERE locked_by NOT IN (SELECT pid FROM pg_stat_activity);")
105
110
  end
111
+
112
+ private
113
+ def self.rails_connection_sharing_enabled?
114
+ enabled = ENV.fetch('QC_RAILS_DATABASE', 'true') != 'false'
115
+ return false unless enabled
116
+ return Object.const_defined?("ActiveRecord") && ActiveRecord::Base.respond_to?("connection")
117
+ end
106
118
  end
107
119
 
108
120
  require_relative "queue_classic/queue"
@@ -64,8 +64,7 @@ module QC
64
64
 
65
65
  def validate!(c)
66
66
  return c if c.is_a?(PG::Connection)
67
- klass = c.class
68
- err = "connection must be an instance of PG::Connection, but was #{c}"
67
+ err = "connection must be an instance of PG::Connection, but was #{c.class}"
69
68
  raise(ArgumentError, err)
70
69
  end
71
70
 
@@ -94,7 +93,7 @@ module QC
94
93
  end
95
94
 
96
95
  def db_url
97
- return @db_url if @db_url
96
+ return @db_url if defined?(@db_url) && @db_url
98
97
  url = ENV["QC_DATABASE_URL"] ||
99
98
  ENV["DATABASE_URL"] ||
100
99
  raise(ArgumentError, "missing QC_DATABASE_URL or DATABASE_URL")
@@ -36,7 +36,30 @@ module QC
36
36
  # `'hello', 'world'`.
37
37
  def enqueue(method, *args)
38
38
  QC.log_yield(:measure => 'queue.enqueue') do
39
- s="INSERT INTO #{TABLE_NAME} (q_name, method, args) VALUES ($1, $2, $3)"
39
+ s = "INSERT INTO #{TABLE_NAME} (q_name, method, args) VALUES ($1, $2, $3)"
40
+ conn_adapter.execute(s, name, method, JSON.dump(args))
41
+ end
42
+ end
43
+
44
+ # enqueue_at(t,m,a) inserts a row into the jobs table representing a job
45
+ # to be executed not before the specified time.
46
+ # The time argument must be a Time object or a float timestamp. The method
47
+ # and args argument must be in the form described in the documentation for
48
+ # the #enqueue method.
49
+ def enqueue_at(timestamp, method, *args)
50
+ offset = Time.at(timestamp) - Time.now
51
+ enqueue_in(offset, method, *args)
52
+ end
53
+
54
+ # enqueue_in(t,m,a) inserts a row into the jobs table representing a job
55
+ # to be executed not before the specified time offset.
56
+ # The seconds argument must be an integer. The method and args argument
57
+ # must be in the form described in the documentation for the #enqueue
58
+ # method.
59
+ def enqueue_in(seconds, method, *args)
60
+ QC.log_yield(:measure => 'queue.enqueue') do
61
+ s = "INSERT INTO #{TABLE_NAME} (q_name, method, args, scheduled_at)
62
+ VALUES ($1, $2, $3, now() + interval '#{seconds.to_i} seconds')"
40
63
  res = conn_adapter.execute(s, name, method, JSON.dump(args))
41
64
  end
42
65
  end
@@ -50,9 +73,9 @@ module QC
50
73
  job[:q_name] = r["q_name"]
51
74
  job[:method] = r["method"]
52
75
  job[:args] = JSON.parse(r["args"])
53
- if r["created_at"]
54
- job[:created_at] = Time.parse(r["created_at"])
55
- ttl = Integer((Time.now - job[:created_at]) * 1000)
76
+ if r["scheduled_at"]
77
+ job[:scheduled_at] = Time.parse(r["scheduled_at"])
78
+ ttl = Integer((Time.now - job[:scheduled_at]) * 1000)
56
79
  QC.measure("time-to-lock=#{ttl}ms source=#{name}")
57
80
  end
58
81
  end
@@ -6,6 +6,8 @@ module QC
6
6
  DropSqlFunctions = File.join(Root, "/sql/drop_ddl.sql")
7
7
  UpgradeTo_3_0_0 = File.join(Root, "/sql/update_to_3_0_0.sql")
8
8
  DowngradeFrom_3_0_0 = File.join(Root, "/sql/downgrade_from_3_0_0.sql")
9
+ UpgradeTo_3_1_0 = File.join(Root, "/sql/update_to_3_1_0.sql")
10
+ DowngradeFrom_3_1_0 = File.join(Root, "/sql/downgrade_from_3_1_0.sql")
9
11
 
10
12
  def self.create(c = QC::default_conn_adapter.connection)
11
13
  conn = QC::ConnAdapter.new(c)
@@ -24,6 +26,7 @@ module QC
24
26
  def self.update(c = QC::default_conn_adapter.connection)
25
27
  conn = QC::ConnAdapter.new(c)
26
28
  conn.execute(File.read(UpgradeTo_3_0_0))
29
+ conn.execute(File.read(UpgradeTo_3_1_0))
27
30
  conn.execute(File.read(DropSqlFunctions))
28
31
  conn.execute(File.read(SqlFunctions))
29
32
  end
@@ -39,5 +42,17 @@ module QC
39
42
  conn = QC::ConnAdapter.new(c)
40
43
  conn.execute(File.read(DowngradeFrom_3_0_0))
41
44
  end
45
+
46
+ def self.update_to_3_1_0(c = QC::default_conn_adapter.connection)
47
+ conn = QC::ConnAdapter.new(c)
48
+ conn.execute(File.read(UpgradeTo_3_1_0))
49
+ conn.execute(File.read(DropSqlFunctions))
50
+ conn.execute(File.read(SqlFunctions))
51
+ end
52
+
53
+ def self.downgrade_from_3_1_0(c = QC::default_conn_adapter.connection)
54
+ conn = QC::ConnAdapter.new(c)
55
+ conn.execute(File.read(DowngradeFrom_3_1_0))
56
+ end
42
57
  end
43
58
  end
data/readme.md CHANGED
@@ -1,15 +1,29 @@
1
1
  # queue_classic
2
2
 
3
- [![Build Status](https://travis-ci.org/QueueClassic/queue_classic.svg?branch=master)](https://travis-ci.org/QueueClassic/queue_classic)
4
- [![Code Climate](https://codeclimate.com/github/QueueClassic/queue_classic.png)](https://codeclimate.com/github/QueueClassic/queue_classic)
3
+ <p align="center">
4
+ <b>Simple, efficient worker queue for Ruby & PostgreSQL</b>
5
+ <br />
6
+ <a href="https://travis-ci.org/QueueClassic/queue_classic"><img src="http://img.shields.io/travis/QueueClassic/queue_classic/master.svg?style=flat" /></a>
7
+
8
+ <a href="https://codeclimate.com/github/QueueClassic/queue_classic"><img src="http://img.shields.io/codeclimate/github/QueueClassic/queue_classic.svg?style=flat" /></a>
9
+
10
+ <a href="http://badge.fury.io/rb/queue_classic"><img src="http://img.shields.io/gem/v/queue_classic.svg?style=flat" alt="Gem Version" height="18"></a>
11
+ </p>
12
+
13
+
14
+ **IMPORTANT NOTE REGARDING VERSIONS**
15
+
16
+ **This README is representing the current work for queue_classic 3.1, which is neither complete or stable. You can find the README for stable versions:**
17
+
18
+ - latest stable can be found: [v3.0.X](https://github.com/QueueClassic/queue_classic/tree/3-0-stable)
19
+ - older stable: [v2.2.3](https://github.com/QueueClassic/queue_classic/tree/v2.2.3)
5
20
 
6
- Current: v3.0.X
7
- Older stable: [v2.2.3](https://github.com/QueueClassic/queue_classic/tree/v2.2.3)
8
21
 
22
+ ## What is queue_classic?
9
23
 
10
24
  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.
11
25
 
12
- Features:
26
+ ## Features
13
27
 
14
28
  * Leverage of PostgreSQL's listen/notify & row locking.
15
29
  * Support for multiple queues with heterogeneous workers.
@@ -18,12 +32,12 @@ Features:
18
32
  * Workers can work multiple queues.
19
33
  * Reduced row contention using a [relaxed FIFO](http://www.cs.tau.ac.il/~shanir/nir-pubs-web/Papers/Lock_Free.pdf) technique.
20
34
 
21
- Contents:
35
+ ## Table of content
22
36
 
23
37
  * [Documentation](http://rubydoc.info/gems/queue_classic/2.2.3/frames)
24
38
  * [Usage](#usage)
25
39
  * [Setup](#setup)
26
- * [Upgrade from V2 to V3](#upgrade-from-v2-to-v3)
40
+ * [Upgrade from earlier versions to V3.1](#upgrade-from-earlier-versions)
27
41
  * [Configuration](#configuration)
28
42
  * [JSON](#json)
29
43
  * [Logging](#logging)
@@ -63,6 +77,16 @@ p_queue = QC::Queue.new("priority_queue")
63
77
  p_queue.enqueue("Kernel.puts", ["hello", "world"])
64
78
  ```
65
79
 
80
+ There is also the possibility to schedule a job at a specified time in the future. It will not be worked off before that specified time.
81
+
82
+ ```ruby
83
+ # Specifying the job execution time exactly.
84
+ QC.enqueue_at(Time.new(2024,01,02,10,00), "Kernel.puts", "hello future")
85
+
86
+ # Specifying the job execution time as an offset in seconds.
87
+ QC.enqueue_in(60, "Kernel.puts", "hello from 1 minute later")
88
+ ```
89
+
66
90
  ### Working Jobs
67
91
 
68
92
  There are two ways to work jobs. The first approach is to use the Rake task. The second approach is to use a custom executable.
@@ -88,7 +112,7 @@ $ QUEUE="priority_queue" bundle exec rake qc:work
88
112
 
89
113
  Setup a worker to work multiple queues.
90
114
  ```bash
91
- $ QUEUES="priority_queue, secondary_queue" bundle exec rake qc:work
115
+ $ QUEUES="priority_queue,secondary_queue" bundle exec rake qc:work
92
116
  ```
93
117
  In this scenario, on each iteration of the worker's loop, it will look for jobs in the first queue prior to looking at the second queue. This means that the first queue must be empty before the worker will look at the second queue.
94
118
 
@@ -148,17 +172,7 @@ rails generate queue_classic:install
148
172
  rake db:migrate
149
173
  ```
150
174
 
151
- 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.
152
-
153
- You can share your active record connection with queue_classic –**however this is not thread safe.**
154
-
155
- ```ruby
156
- require 'queue_classic'
157
- QC.default_conn_adapter = QC::ConnAdapter.new(
158
- ActiveRecord::Base.connection.raw_connection)
159
- ```
160
-
161
- **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.
175
+ If you want to use queue_classic with Active Job (Rails 4.2+), you need to set `Rails.application.config.active_job.queue_adapter = :queue_classic`. Everything else will be taken care for you, just use the Active Job API.
162
176
 
163
177
  ### Rake Task Setup
164
178
 
@@ -172,7 +186,22 @@ $ bundle exec rake qc:create
172
186
  $ bundle exec rake qc:drop
173
187
  ```
174
188
 
175
- ## Upgrade from V2 to V3
189
+ ### Database connection
190
+
191
+ #### Ruby on Rails
192
+
193
+ Starting with with queue_classic 3.1, Rails is automatically detected and its connection is used.
194
+
195
+ If you don't want to use the automatic database connection, set this environment variable to false: `export QC_RAILS_DATABASE=false`
196
+
197
+ **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.
198
+
199
+
200
+ #### Other Ruby apps
201
+
202
+ 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.
203
+
204
+ ## Upgrade from earlier versions
176
205
  If you are upgrading from a previous version of queue_classic, you might need some new database columns and/or functions. Luckily enough for you, it is easy to do so.
177
206
 
178
207
  ### Ruby on Rails
@@ -7,7 +7,8 @@ CREATE TABLE queue_classic_jobs (
7
7
  args text not null,
8
8
  locked_at timestamptz,
9
9
  locked_by integer,
10
- created_at timestamptz default now()
10
+ created_at timestamptz default now(),
11
+ scheduled_at timestamptz default now()
11
12
  );
12
13
 
13
14
  -- If json type is available, use it for the args column.
@@ -19,3 +20,5 @@ end if;
19
20
  end $$ language plpgsql;
20
21
 
21
22
  CREATE INDEX idx_qc_on_name_only_unlocked ON queue_classic_jobs (q_name, id) WHERE locked_at IS NULL;
23
+ CREATE INDEX idx_qc_on_scheduled_at_only_unlocked ON queue_classic_jobs (scheduled_at, id) WHERE locked_at IS NULL;
24
+
@@ -19,6 +19,8 @@ BEGIN
19
19
  || ' WHERE locked_at IS NULL'
20
20
  || ' AND q_name = '
21
21
  || quote_literal(q_name)
22
+ || ' AND scheduled_at <= '
23
+ || quote_literal(now())
22
24
  || ' LIMIT '
23
25
  || quote_literal(top_boundary)
24
26
  || ') limited'
@@ -37,6 +39,8 @@ BEGIN
37
39
  || ' WHERE locked_at IS NULL'
38
40
  || ' AND q_name = '
39
41
  || quote_literal(q_name)
42
+ || ' AND scheduled_at <= '
43
+ || quote_literal(now())
40
44
  || ' ORDER BY id ASC'
41
45
  || ' LIMIT 1'
42
46
  || ' OFFSET ' || quote_literal(relative_top)
@@ -0,0 +1 @@
1
+ ALTER TABLE queue_classic_jobs DROP COLUMN scheduled_at;
@@ -0,0 +1,9 @@
1
+ DO $$DECLARE r record;
2
+ BEGIN
3
+ BEGIN
4
+ ALTER TABLE queue_classic_jobs ADD COLUMN scheduled_at timestamptz default now();
5
+ CREATE INDEX idx_qc_on_scheduled_at_only_unlocked ON queue_classic_jobs (scheduled_at, id) WHERE locked_at IS NULL;
6
+ EXCEPTION
7
+ WHEN duplicate_column THEN RAISE NOTICE 'column scheduled_at already exists in queue_classic_jobs.';
8
+ END;
9
+ END$$;
@@ -0,0 +1,40 @@
1
+ require File.expand_path("../../helper.rb", __FILE__)
2
+
3
+ class QueueClassicRailsConnectionTest < QCTest
4
+ def before_setup
5
+ Object.send :const_set, :ActiveRecord, Module.new
6
+ ActiveRecord.const_set :Base, Module.new
7
+
8
+ QC.default_conn_adapter = nil
9
+ end
10
+
11
+ def after_teardown
12
+ ActiveRecord.send :remove_const, :Base
13
+ Object.send :remove_const, :ActiveRecord
14
+ end
15
+
16
+ def test_uses_active_record_connection_if_exists
17
+ connection = get_connection
18
+ assert connection.verify
19
+ end
20
+
21
+ def test_does_not_use_active_record_connection_if_env_var_set
22
+ ENV['QC_RAILS_DATABASE'] = 'false'
23
+ connection = get_connection
24
+ assert_raises(MockExpectationError) { connection.verify }
25
+ ENV['QC_RAILS_DATABASE'] = 'true'
26
+ end
27
+
28
+ private
29
+ def get_connection
30
+ connection = Minitest::Mock.new
31
+ connection.expect(:raw_connection, QC::ConnAdapter.new.connection)
32
+
33
+ ActiveRecord::Base.define_singleton_method(:connection) do
34
+ connection
35
+ end
36
+
37
+ QC.default_conn_adapter
38
+ connection
39
+ end
40
+ end
@@ -27,6 +27,35 @@ class QueueTest < QCTest
27
27
  assert_nil(QC.lock)
28
28
  end
29
29
 
30
+ def test_lock_with_future_job_with_enqueue_in
31
+ QC.enqueue_in(2, "Klass.method")
32
+ assert_nil QC.lock
33
+ sleep 2
34
+ job = QC.lock
35
+ assert_equal("Klass.method", job[:method])
36
+ assert_equal([], job[:args])
37
+ end
38
+
39
+ def test_lock_with_future_job_with_enqueue_at_with_a_time_object
40
+ future = Time.now + 2
41
+ QC.enqueue_at(future, "Klass.method")
42
+ assert_nil QC.lock
43
+ until Time.now >= future do sleep 0.1 end
44
+ job = QC.lock
45
+ assert_equal("Klass.method", job[:method])
46
+ assert_equal([], job[:args])
47
+ end
48
+
49
+ def test_lock_with_future_job_with_enqueue_at_with_a_float_timestamp
50
+ offset = (Time.now + 2).to_f
51
+ QC.enqueue_at(offset, "Klass.method")
52
+ assert_nil QC.lock
53
+ sleep 2
54
+ job = QC.lock
55
+ assert_equal("Klass.method", job[:method])
56
+ assert_equal([], job[:args])
57
+ end
58
+
30
59
  def test_count
31
60
  QC.enqueue("Klass.method")
32
61
  assert_equal(1, QC.count)
@@ -179,7 +179,7 @@ class WorkerTest < QCTest
179
179
  set_database 'postgres:///invalid'
180
180
 
181
181
  conn = PG::Connection.connect(dbname: 'queue_classic_test')
182
- worker = QC::Worker.new connection: conn
182
+ QC::Worker.new connection: conn
183
183
 
184
184
  conn.close
185
185
  reset_database
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: queue_classic
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.3
4
+ version: 3.1.0.RC1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Smith (♠ ace hacker)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-05 00:00:00.000000000 Z
11
+ date: 2015-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg
@@ -42,6 +42,7 @@ files:
42
42
  - lib/generators/queue_classic/templates/add_queue_classic.rb
43
43
  - lib/generators/queue_classic/templates/update_queue_classic_3_0_0.rb
44
44
  - lib/generators/queue_classic/templates/update_queue_classic_3_0_2.rb
45
+ - lib/generators/queue_classic/templates/update_queue_classic_3_1_0.rb
45
46
  - lib/queue_classic.rb
46
47
  - lib/queue_classic/conn_adapter.rb
47
48
  - lib/queue_classic/queue.rb
@@ -53,10 +54,13 @@ files:
53
54
  - sql/create_table.sql
54
55
  - sql/ddl.sql
55
56
  - sql/downgrade_from_3_0_0.sql
57
+ - sql/downgrade_from_3_1_0.sql
56
58
  - sql/drop_ddl.sql
57
59
  - sql/update_to_3_0_0.sql
60
+ - sql/update_to_3_1_0.sql
58
61
  - test/benchmark_test.rb
59
62
  - test/helper.rb
63
+ - test/lib/queue_classic_rails_connection_test.rb
60
64
  - test/lib/queue_classic_test.rb
61
65
  - test/queue_test.rb
62
66
  - test/worker_test.rb
@@ -75,9 +79,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
75
79
  version: '0'
76
80
  required_rubygems_version: !ruby/object:Gem::Requirement
77
81
  requirements:
78
- - - ">="
82
+ - - ">"
79
83
  - !ruby/object:Gem::Version
80
- version: '0'
84
+ version: 1.3.1
81
85
  requirements: []
82
86
  rubyforge_project:
83
87
  rubygems_version: 2.2.2
@@ -86,6 +90,7 @@ specification_version: 4
86
90
  summary: Simple, efficient worker queue for Ruby & PostgreSQL.
87
91
  test_files:
88
92
  - test/benchmark_test.rb
93
+ - test/lib/queue_classic_rails_connection_test.rb
89
94
  - test/lib/queue_classic_test.rb
90
95
  - test/queue_test.rb
91
96
  - test/worker_test.rb