pgbus 0.3.1 → 0.3.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6daa2060697774db5018b30b2d7b08ef4f3f962332e627f8fa90ce49cfe136da
4
- data.tar.gz: 9fe928dba25e277212093a6e1a0443c6451336b2bc996e06375d88eaaf2dd148
3
+ metadata.gz: d895049be3463d74d039e29485fc7d26c4c06ca96419e8a46327a4be6538db1f
4
+ data.tar.gz: f685673eaf24780e820486b9eb1f752493caf1765241b0063293d1d8d4b98e25
5
5
  SHA512:
6
- metadata.gz: 1977d39318814b8878eef04065e4abf2a73588005542e5b15b679248848fd470c11b685a3a7c2d89d26ecbee0b897fa2968d498b757b0435bf213eba61e48c3d
7
- data.tar.gz: 0d999aa34400b0a9f85e030d9cd5ac9f5bb0b57e467eee50615a3cf6f19ee70f8c33da688b3d78abf575c4c053e0dab7ecc3fbc2c841390c97d9089b2f238135
6
+ metadata.gz: 33cb5c4fbf7ae36a8bb82a780d39bd0a32fd2c3167d0d7aaaed74a60608778a90e32eac53c1db2808ffa5956184298a83478488a8d11edcc89b052ec5fe8b0a5
7
+ data.tar.gz: 4a9cc394b02ee99e1681ab26a86db25c57f38f92e901dab0c2c48c1025224bb4089009abcd865a2432c3b37a988b51511faa64be976709069a4dbef70e3ec5ed
data/Rakefile CHANGED
@@ -31,7 +31,12 @@ namespace :bench do
31
31
  ruby "benchmarks/memory_profile.rb"
32
32
  end
33
33
 
34
- desc "Run all benchmarks"
34
+ desc "Run integration benchmarks (requires PGBUS_DATABASE_URL)"
35
+ task :integration do
36
+ ruby "benchmarks/integration_bench.rb"
37
+ end
38
+
39
+ desc "Run all benchmarks (unit-level, no DB required)"
35
40
  task all: %i[serialization client executor]
36
41
  end
37
42
 
@@ -16,42 +16,50 @@ module Pgbus
16
16
  # Atomically try to acquire a lock.
17
17
  # Cleans up expired locks for this key first (crash recovery at acquire time).
18
18
  # Returns true if acquired, false if already locked.
19
- def self.acquire!(lock_key, job_class:, ttl:, job_id: nil, state: "queued", owner_pid: nil, owner_hostname: nil)
19
+ #
20
+ # Uses raw SQL on the hot path to minimize ActiveRecord allocations
21
+ # (~29 objects vs ~304 per acquire+release cycle with AR query builder).
22
+ def self.acquire!(lock_key, job_class:, ttl:, job_id: nil, state: "queued", owner_pid: nil, owner_hostname: nil) # rubocop:disable Naming/PredicateMethod
23
+ expires_at = Time.current + ttl
24
+
20
25
  # Remove any expired lock for this key inline (last-resort TTL recovery)
21
- where(lock_key: lock_key).where("expires_at < ?", Time.current).delete_all
26
+ connection.exec_delete(
27
+ "DELETE FROM #{table_name} WHERE lock_key = $1 AND expires_at < $2",
28
+ "JobLock Expire", [lock_key, Time.current]
29
+ )
22
30
 
23
- result = insert(
24
- {
25
- lock_key: lock_key, job_class: job_class, job_id: job_id,
26
- state: state, owner_pid: owner_pid, owner_hostname: owner_hostname,
27
- expires_at: Time.current + ttl
28
- },
29
- unique_by: :lock_key
31
+ result = connection.exec_query(
32
+ "INSERT INTO #{table_name} (lock_key, job_class, job_id, state, owner_pid, owner_hostname, expires_at) " \
33
+ "VALUES ($1, $2, $3, $4, $5, $6, $7) ON CONFLICT (lock_key) DO NOTHING RETURNING id",
34
+ "JobLock Acquire", [lock_key, job_class, job_id, state, owner_pid, owner_hostname, expires_at]
30
35
  )
31
36
  result.rows.any?
32
- rescue ActiveRecord::RecordNotUnique
33
- false
34
37
  end
35
38
 
36
39
  # Transition a queued lock to executing state and claim ownership.
37
40
  # Called when a worker starts executing a job that was locked at enqueue time.
38
41
  def self.claim_for_execution!(lock_key, owner_pid:, owner_hostname:, ttl:)
39
- where(lock_key: lock_key).update_all(
40
- state: "executing",
41
- owner_pid: owner_pid,
42
- owner_hostname: owner_hostname,
43
- expires_at: Time.current + ttl
42
+ connection.exec_update(
43
+ "UPDATE #{table_name} SET state = $1, owner_pid = $2, owner_hostname = $3, expires_at = $4 " \
44
+ "WHERE lock_key = $5",
45
+ "JobLock Claim", ["executing", owner_pid, owner_hostname, Time.current + ttl, lock_key]
44
46
  )
45
47
  end
46
48
 
47
49
  # Release a lock by key.
48
50
  def self.release!(lock_key)
49
- where(lock_key: lock_key).delete_all
51
+ connection.exec_delete(
52
+ "DELETE FROM #{table_name} WHERE lock_key = $1",
53
+ "JobLock Release", [lock_key]
54
+ )
50
55
  end
51
56
 
52
57
  # Check if a lock is currently held (regardless of expiry — reaper handles orphans).
53
58
  def self.locked?(lock_key)
54
- where(lock_key: lock_key).exists?
59
+ result = connection.select_value(
60
+ "SELECT 1 FROM #{table_name} WHERE lock_key = $1 LIMIT 1", "JobLock Check", [lock_key]
61
+ )
62
+ !result.nil?
55
63
  end
56
64
 
57
65
  # Reap orphaned locks: locks in 'executing' state whose owner_pid
data/lib/pgbus/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Pgbus
4
- VERSION = "0.3.1"
4
+ VERSION = "0.3.2"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pgbus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikael Henriksson