Class: Wurk::TransactionAwareClient

Inherits:
Object
  • Object
show all
Defined in:
lib/wurk/transaction_aware_client.rb

Overview

Opt-in enqueue client that holds each ‘push` until the surrounding ActiveRecord transaction commits, so a job never references a row a rollback erased — the canonical “enqueue after commit” pattern.

Enable globally with ‘Wurk.transactional_push!` (aliased `Sidekiq.transactional_push!`), which sets `default_job_options [“client_class”]`; the worker DSL then builds this client instead of the plain `Wurk::Client`.

The jid is pre-allocated and returned synchronously so the caller can reference it inside the transaction; the actual Redis write runs in an after-commit hook. ‘push_bulk` is intentionally NOT deferred — it matches Sidekiq, whose batching/scheduling machinery can’t ride the commit hook.

Spec: docs/target/sidekiq-free.md §8.

Instance Method Summary collapse

Constructor Details

#initialize(pool: nil, config: nil) ⇒ TransactionAwareClient

Returns a new instance of TransactionAwareClient.



24
25
26
# File 'lib/wurk/transaction_aware_client.rb', line 24

def initialize(pool: nil, config: nil)
  @redis_client = Wurk::Client.new(pool: pool, config: config)
end

Instance Method Details

#batching?Boolean

True inside a ‘Batch#jobs` block. The batch counts jobs at push time, so deferring would desync its totals — push immediately instead.

Returns:

  • (Boolean)


30
31
32
# File 'lib/wurk/transaction_aware_client.rb', line 30

def batching?
  !Thread.current[Wurk::Batch::THREAD_KEY].nil?
end

#push(item) ⇒ String

Returns the pre-allocated jid (returned before the deferred push runs).

Returns:

  • (String)

    the pre-allocated jid (returned before the deferred push runs).



35
36
37
38
39
40
41
42
43
44
45
# File 'lib/wurk/transaction_aware_client.rb', line 35

def push(item)
  item['jid'] ||= SecureRandom.hex(12)

  if batching?
    @redis_client.push(item)
  else
    register_after_commit { @redis_client.push(item) }
  end

  item['jid']
end

#push_bulk(items) ⇒ Object

Bulk enqueue is never transactional (Sidekiq parity) — straight to Redis.



48
49
50
# File 'lib/wurk/transaction_aware_client.rb', line 48

def push_bulk(items)
  @redis_client.push_bulk(items)
end