Class: Wurk::Batch::Status

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

Overview

Snapshot of a batch’s state — read-only view backed by HGETALL of ‘b-<bid>` plus the supporting JIDs/failed/died sets. Mirrors the Sidekiq::Batch::Status surface from docs/target/sidekiq-pro.md §2.5.

‘#data` returns the JSON-friendly hash served by the polling endpoint. `#join` blocks the current thread until `complete?` — test/util only. `#delete` UNLINKs every key associated with the batch.

Constant Summary collapse

JOIN_POLL_INTERVAL =
0.5

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bid) ⇒ Status

Returns a new instance of Status.

Raises:

  • (ArgumentError)


19
20
21
22
23
24
# File 'lib/wurk/batch/status.rb', line 19

def initialize(bid)
  raise ArgumentError, 'bid required' if bid.nil? || bid.to_s.empty?

  @bid = bid.to_s
  reload!
end

Instance Attribute Details

#bidObject (readonly)

Returns the value of attribute bid.



17
18
19
# File 'lib/wurk/batch/status.rb', line 17

def bid
  @bid
end

Instance Method Details

#callback_queueObject



40
# File 'lib/wurk/batch/status.rb', line 40

def callback_queue   = @data['callback_queue']

#child_countObject



61
62
63
# File 'lib/wurk/batch/status.rb', line 61

def child_count
  Wurk.redis { |conn| conn.call('SCARD', "b-#{@bid}-kids") }.to_i
end

#complete?Boolean

‘:complete` fires when the live jids set is empty (every job has either succeeded or died). Hash field is set by the server callback; falling back to a recompute keeps Status accurate even if the callback dispatch is in flight.

Returns:

  • (Boolean)


47
48
49
50
51
# File 'lib/wurk/batch/status.rb', line 47

def complete?
  return true if @data['complete'] == '1'

  total.positive? && live_jids_count.zero?
end

#complete_atObject



35
# File 'lib/wurk/batch/status.rb', line 35

def complete_at      = numeric_or_nil(@data['complete_at'])

#created_atObject



34
# File 'lib/wurk/batch/status.rb', line 34

def created_at       = numeric_or_nil(@data['created_at'])

#dataObject

JSON-serializable snapshot used by the polling middleware / web UI. Field names are wire-compat with Sidekiq Pro’s BatchStatus.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/wurk/batch/status.rb', line 76

def data
  {
    'bid' => @bid,
    'total' => total,
    'pending' => pending,
    'failures' => failures,
    'created_at' => created_at,
    'complete_at' => complete_at,
    'success_at' => success_at,
    'death_at' => death_at,
    'complete' => complete?,
    'invalidated' => invalidated?,
    'description' => description,
    'parent_bid' => parent_bid,
    'tags' => tags,
    'failed_jids' => failed_jids,
    'dead_jids' => dead_jids,
    'child_count' => child_count
  }
end

#dead_jidsObject



57
58
59
# File 'lib/wurk/batch/status.rb', line 57

def dead_jids
  Wurk.redis { |conn| conn.call('SMEMBERS', "b-#{@bid}-died") }
end

#death_atObject



37
# File 'lib/wurk/batch/status.rb', line 37

def death_at         = numeric_or_nil(@data['death_at'])

#deleteObject

Nukes every key for this batch. Dangerous if jobs are still in flight — they’ll succeed/fail without a batch to ack against, callbacks won’t fire, and counts get permanently inconsistent. Caller’s problem.



112
113
114
115
116
117
118
119
# File 'lib/wurk/batch/status.rb', line 112

def delete
  Wurk.redis do |conn|
    conn.call('UNLINK', *Batch.keys_for(@bid))
    conn.call('ZREM', 'batches', @bid)
    conn.call('ZREM', 'dead-batches', @bid)
  end
  nil
end

#descriptionObject



38
# File 'lib/wurk/batch/status.rb', line 38

def description      = @data['description']

#exists?Boolean

False when no ‘b-<bid>` hash exists — a well-formed bid that was never created (or has expired). Lets callers 404 instead of serving an all-zero phantom batch.

Returns:

  • (Boolean)


29
# File 'lib/wurk/batch/status.rb', line 29

def exists? = !@data.empty?

#failed_jidsObject



53
54
55
# File 'lib/wurk/batch/status.rb', line 53

def failed_jids
  Wurk.redis { |conn| conn.call('SMEMBERS', "b-#{@bid}-failed") }
end

#failuresObject



33
# File 'lib/wurk/batch/status.rb', line 33

def failures         = @data['failures'].to_i

#invalidated?Boolean

Returns:

  • (Boolean)


41
# File 'lib/wurk/batch/status.rb', line 41

def invalidated?     = @data['invalidated'] == '1'

#joinObject

Blocks the current thread until ‘complete?` is true. Test/util only —polling Redis from a worker thread would defeat the whole point of asynchronous batches.



100
101
102
103
104
105
106
107
# File 'lib/wurk/batch/status.rb', line 100

def join
  loop do
    reload!
    break if complete?

    sleep JOIN_POLL_INTERVAL
  end
end

#parent_bidObject



39
# File 'lib/wurk/batch/status.rb', line 39

def parent_bid       = @data['parent_bid']

#pendingObject



32
# File 'lib/wurk/batch/status.rb', line 32

def pending          = @data['pending'].to_i

#reload!Object



121
122
123
124
125
# File 'lib/wurk/batch/status.rb', line 121

def reload!
  raw = Wurk.redis { |conn| conn.call('HGETALL', "b-#{@bid}") }
  @data = raw.is_a?(Hash) ? raw : raw.each_slice(2).to_h
  self
end

#success_atObject



36
# File 'lib/wurk/batch/status.rb', line 36

def success_at       = numeric_or_nil(@data['success_at'])

#tagsObject



65
66
67
68
69
70
71
72
# File 'lib/wurk/batch/status.rb', line 65

def tags
  raw = @data['tags']
  return [] if raw.nil? || raw.empty?

  JSON.parse(raw)
rescue JSON::ParserError
  []
end

#totalObject



31
# File 'lib/wurk/batch/status.rb', line 31

def total            = @data['total'].to_i