Class: Wurk::Processor

Inherits:
Object
  • Object
show all
Includes:
Component
Defined in:
lib/wurk/processor.rb

Overview

Inside each Manager, N Processors run in parallel. Each owns one thread, pulls a UnitOfWork from the capsule's fetcher, parses the payload, walks the server middleware chain, invokes perform, then ACKs (retires the payload from the per-process private list). The ACK is handed to the fetcher, which pipelines it with the next fetch rather than spending a round trip on it — #flush_acks covers the case where there is no next fetch.

Shutdown is two-stage:

* `terminate` flips a flag; the run loop exits between jobs.
* `kill` additionally raises `Wurk::Shutdown` into the thread so an
in-flight perform unwinds. The current UoW is NOT acked, so the
payload survives in the private list and is reclaimed on next boot.

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

Defined Under Namespace

Classes: Counter, SharedWorkState

Constant Summary collapse

PROCESSED =
Counter.new
FAILURE =
Counter.new
EXPIRED =
Counter.new
WORK_STATE =
SharedWorkState.new

Constants included from Component

Component::DEFAULT_THREAD_PRIORITY, Component::LEADER_CACHE_TTL_MS, Component::PROCESS_NONCE

Instance Attribute Summary collapse

Attributes included from Component

#config

Instance Method Summary collapse

Methods included from Component

#default_tag, #fire_event, #hostname, #identity, #leader?, #logger, #mono_ms, #process_nonce, #real_ms, #redis, #safe_thread, tid, #tid, #watchdog

Constructor Details

#initialize(capsule, &callback) ⇒ Processor

Returns a new instance of Processor.



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/wurk/processor.rb', line 51

def initialize(capsule, &callback)
  @capsule = capsule
  @config = capsule
  @callback = callback
  @done = false
  @job = nil
  @thread = nil
  @reloader = resolve_reloader(capsule.config[:reloader])
  @job_logger = (capsule.config[:job_logger] || JobLogger).new(capsule.config)
  @retrier = JobRetry.new(capsule)
end

Instance Attribute Details

#capsuleObject (readonly)

Returns the value of attribute capsule.



49
50
51
# File 'lib/wurk/processor.rb', line 49

def capsule
  @capsule
end

#jobObject (readonly)

Returns the value of attribute job.



49
50
51
# File 'lib/wurk/processor.rb', line 49

def job
  @job
end

#threadObject (readonly)

Returns the value of attribute thread.



49
50
51
# File 'lib/wurk/processor.rb', line 49

def thread
  @thread
end

Instance Method Details

#handle_exception(ex, ctx = {}) ⇒ Object

Capsule doesn't define handle_exception (it's a Configuration method); override Component's delegation so error handlers fire.



93
94
95
# File 'lib/wurk/processor.rb', line 93

def handle_exception(ex, ctx = {})
  @capsule.config.handle_exception(ex, ctx)
end

#kill(wait = false) ⇒ Object

Hard-stop: flips the flag and unwinds the in-flight job by raising Wurk::Shutdown into the worker thread. The UoW is intentionally not acked — the payload remains in the private list and is reclaimed on next boot via Reliable#bulk_requeue.



75
76
77
78
79
80
81
# File 'lib/wurk/processor.rb', line 75

def kill(wait = false) # rubocop:disable Style/OptionalBooleanParameter
  @done = true
  return if @thread.nil?

  @thread.raise ::Wurk::Shutdown
  @thread.value if wait
end

#process_oneObject

Single iteration: fetch one UoW, process it. Public so tests can drive the loop step-by-step without spawning a thread.



99
100
101
102
103
# File 'lib/wurk/processor.rb', line 99

def process_one
  @job = fetch
  process(@job) if @job
  @job = nil
end

#startObject



87
88
89
# File 'lib/wurk/processor.rb', line 87

def start
  @thread ||= safe_thread("#{@capsule.name}/processor", &method(:run)) # rubocop:disable Naming/MemoizedInstanceVariableName
end

#stopping?Boolean

Returns:

  • (Boolean)


83
84
85
# File 'lib/wurk/processor.rb', line 83

def stopping?
  @done
end

#terminate(wait = false) ⇒ Object

Sidekiq surface — positional boolean to match the drop-in contract.



64
65
66
67
68
69
# File 'lib/wurk/processor.rb', line 64

def terminate(wait = false) # rubocop:disable Style/OptionalBooleanParameter
  @done = true
  return if @thread.nil?

  @thread.value if wait
end