queue_classic_plus 4.0.0.alpha17 → 4.0.0.alpha18

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
  SHA256:
3
- metadata.gz: 3b17bbec023aa5f8fa91527f15c91db3ca6a9975da20c304188b5100757bab9b
4
- data.tar.gz: 57ce60a1dfd1912b7a6b57c6b8c312f78fc3f903dc674739099dc27bb138d8aa
3
+ metadata.gz: f4194444b2e3b6bc8d08ebfe7393e9efa53bc31fdb8c7e79c5b1a6aff31e8776
4
+ data.tar.gz: a12f2b01acea5e2fb4fc6e6b257c6aafc228ff38f73280a3deb974452f2e7220
5
5
  SHA512:
6
- metadata.gz: e45d48b488c7cc0bdea10fbea03397539a5533b1d98647aaf9f942150caaa121dc958bc57cc183782ffc7b74c98305a90ef14c9d07dfcb00b562372bf0c7048b
7
- data.tar.gz: 23932d46b74e4f994b4e8a09d6b81e933f0798fa45608968e63f37b39476de0428c6315ebb925e18b043dabc4b10d0d8336e72d65407f61ba5e678c591d9918a
6
+ metadata.gz: 42399e627f40795df59f4235e6d616527506758af7a988c2e7e923ce3fbad2bac49b188563ad508d66e95f9935149eaafd1928d6eac6c97bfeb9f1a437fffabe
7
+ data.tar.gz: b08d05305a8772d2aacf0e5984b5d2254f3b1f83cb8e6d4d02b7f1bb3d929d70e3ddd02b1130f9845ebec3d9ef409d7a86d63f44ff04ea3fb998dd0cab2080a0
@@ -52,8 +52,32 @@ module QueueClassicPlus
52
52
  QueueClassicPlus.logger
53
53
  end
54
54
 
55
+ def self.can_enqueue?(method, *args)
56
+ if locked?
57
+ max_lock_time = ENV.fetch("QUEUE_CLASSIC_MAX_LOCK_TIME", 10 * 60).to_i
58
+
59
+ q = "SELECT COUNT(1) AS count
60
+ FROM
61
+ (
62
+ SELECT 1
63
+ FROM queue_classic_jobs
64
+ WHERE q_name = $1 AND method = $2 AND args::text = $3::text
65
+ AND (locked_at IS NULL OR locked_at > current_timestamp - interval '#{max_lock_time} seconds')
66
+ LIMIT 1
67
+ )
68
+ AS x"
69
+
70
+ result = QC.default_conn_adapter.execute(q, @queue, method, JSON.dump(serialized(args)))
71
+ result['count'].to_i == 0
72
+ else
73
+ true
74
+ end
75
+ end
76
+
55
77
  def self.enqueue(method, *args)
56
- queue.enqueue(method, *serialized(args), lock: locked?)
78
+ if can_enqueue?(method, *args)
79
+ queue.enqueue(method, *serialized(args))
80
+ end
57
81
  end
58
82
 
59
83
  def self.enqueue_perform(*args)
@@ -50,25 +50,5 @@ module QC
50
50
  end
51
51
  end
52
52
 
53
- def enqueue(method, *args, lock: false)
54
- QC.log_yield(:measure => 'queue.enqueue') do
55
- insert_sql = <<-EOF
56
- INSERT INTO #{QC.table_name} (q_name, method, args, lock)
57
- VALUES ($1, $2, $3, $4)
58
- ON CONFLICT (q_name, method, args) WHERE lock IS TRUE DO NOTHING
59
- RETURNING id
60
- EOF
61
- begin
62
- retries ||= 0
63
- conn_adapter.execute(insert_sql, name, method, JSON.dump(args), lock)
64
- rescue PG::Error => error
65
- if (retries += 1) < 2
66
- retry
67
- else
68
- raise
69
- end
70
- end
71
- end
72
- end
73
53
  end
74
54
  end
@@ -1,3 +1,3 @@
1
1
  module QueueClassicPlus
2
- VERSION = '4.0.0.alpha17'.freeze
2
+ VERSION = '4.0.0.alpha18'.freeze
3
3
  end
@@ -15,18 +15,14 @@ module QueueClassicPlus
15
15
 
16
16
  def self.migrate(c = QC::default_conn_adapter.connection)
17
17
  conn = QC::ConnAdapter.new(connection: c)
18
- conn.execute("ALTER TABLE queue_classic_jobs ADD COLUMN IF NOT EXISTS last_error TEXT")
19
- conn.execute("ALTER TABLE queue_classic_jobs ADD COLUMN IF NOT EXISTS remaining_retries INTEGER")
20
- conn.execute("ALTER TABLE queue_classic_jobs ADD COLUMN IF NOT EXISTS lock BOOLEAN NOT NULL DEFAULT FALSE")
21
- conn.execute("CREATE UNIQUE INDEX IF NOT EXISTS index_queue_classic_jobs_enqueue_lock on queue_classic_jobs(q_name, method, args) WHERE lock IS TRUE")
18
+ conn.execute("ALTER TABLE queue_classic_jobs ADD COLUMN last_error TEXT")
19
+ conn.execute("ALTER TABLE queue_classic_jobs ADD COLUMN remaining_retries INTEGER")
22
20
  end
23
21
 
24
22
  def self.demigrate(c = QC::default_conn_adapter.connection)
25
23
  conn = QC::ConnAdapter.new(connection: c)
26
- conn.execute("ALTER TABLE queue_classic_jobs DROP COLUMN IF EXISTS last_error")
27
- conn.execute("ALTER TABLE queue_classic_jobs DROP COLUMN IF EXISTS remaining_retries")
28
- conn.execute("DROP INDEX IF EXISTS index_queue_classic_jobs_enqueue_lock")
29
- conn.execute("ALTER TABLE queue_classic_jobs DROP COLUMN IF EXISTS lock")
24
+ conn.execute("ALTER TABLE queue_classic_jobs DROP COLUMN last_error")
25
+ conn.execute("ALTER TABLE queue_classic_jobs DROP COLUMN remaining_retries")
30
26
  end
31
27
 
32
28
  def self.exception_handler
data/spec/base_spec.rb CHANGED
@@ -3,24 +3,6 @@ require 'active_record'
3
3
 
4
4
  describe QueueClassicPlus::Base do
5
5
  context "A child of QueueClassicPlus::Base" do
6
- subject do
7
- Class.new(QueueClassicPlus::Base) do
8
- @queue = :test
9
- end
10
- end
11
-
12
- it "allows multiple enqueues" do
13
- threads = []
14
- 10.times do
15
- threads << Thread.new do
16
- subject.do
17
- end
18
- end
19
- threads.each(&:join)
20
-
21
- expect(subject).to have_queue_size_of(10)
22
- end
23
-
24
6
  context "that is locked" do
25
7
  subject do
26
8
  Class.new(QueueClassicPlus::Base) do
@@ -30,28 +12,9 @@ describe QueueClassicPlus::Base do
30
12
  end
31
13
 
32
14
  it "does not allow multiple enqueues" do
33
- threads = []
34
- 10.times do
35
- threads << Thread.new do
36
- subject.do
37
- expect(subject).to have_queue_size_of(1)
38
- end
39
- end
40
- threads.each(&:join)
41
- end
42
-
43
- it "allows enqueueing same job with different arguments" do
44
- threads = []
45
- (1..3).each do |arg|
46
- 10.times do
47
- threads << Thread.new do
48
- subject.do(arg)
49
- end
50
- end
51
- end
52
- threads.each(&:join)
53
-
54
- expect(subject).to have_queue_size_of(3)
15
+ subject.do
16
+ subject.do
17
+ expect(subject).to have_queue_size_of(1)
55
18
  end
56
19
 
57
20
  it "checks for an existing job using the same serializing as job enqueuing" do
@@ -65,22 +28,13 @@ describe QueueClassicPlus::Base do
65
28
  subject.do(date)
66
29
  expect(subject).to have_queue_size_of(1)
67
30
  end
68
- end
69
-
70
- context "when in a transaction" do
71
- subject do
72
- Class.new(QueueClassicPlus::Base) do
73
- @queue = :test
74
- lock!
75
- end
76
- end
77
31
 
78
- it "does not create another transaction when enqueueing" do
79
- conn = QC.default_conn_adapter.connection
80
- expect(conn).to receive(:transaction).exactly(1).times.and_call_original
81
- conn.transaction do
82
- subject.do
83
- end
32
+ it "does allow multiple enqueues if something got locked for too long" do
33
+ subject.do
34
+ one_day_ago = Time.now - 60*60*24
35
+ execute "UPDATE queue_classic_jobs SET locked_at = '#{one_day_ago}' WHERE q_name = 'test'"
36
+ subject.do
37
+ expect(subject).to have_queue_size_of(2)
84
38
  end
85
39
  end
86
40
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: queue_classic_plus
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.alpha17
4
+ version: 4.0.0.alpha18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Mathieu
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-08-22 00:00:00.000000000 Z
13
+ date: 2023-09-06 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: queue_classic