Class: Wurk::SortedEntry

Inherits:
JobRecord show all
Defined in:
lib/wurk/sorted_entry.rb

Overview

One entry inside a sorted-set view (Retry/Scheduled/Dead). Carries the member’s ‘score` alongside the JobRecord so callers can re-target the exact (score, value) pair when mutating Redis — sorted-set membership is by value, but ZREM-by-value is faster than ZRANGEBYSCORE+filter.

The ‘id` field (“<score>|<jid>”) is the Sidekiq wire-compat identifier used by dashboards and third-party tooling. Don’t reformat it.

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

Constant Summary

Constants inherited from JobRecord

JobRecord::ACTION_MAILER_JOBS, JobRecord::ACTIVE_JOB_WRAPPER

Instance Attribute Summary collapse

Attributes inherited from JobRecord

#queue

Instance Method Summary collapse

Methods inherited from JobRecord

#[], #args, #bid, #created_at, #display_args, #display_class, #enqueued_at, #error_backtrace, #failed_at, #item, #iterable_state, #jid, #klass, #latency, latency_from, #retried_at, #tags, #value

Constructor Details

#initialize(parent, score, item) ⇒ SortedEntry

Returns a new instance of SortedEntry.

Parameters:

  • parent (JobSet, nil)

    the owning set; nil when constructed bare.

  • score (Numeric)

    ZSET score (Float seconds since epoch).

  • item (String, Hash)

    raw JSON or parsed payload.



21
22
23
24
25
# File 'lib/wurk/sorted_entry.rb', line 21

def initialize(parent, score, item)
  super(item)
  @score = score.to_f
  @parent = parent
end

Instance Attribute Details

#parentObject (readonly)

Returns the value of attribute parent.



16
17
18
# File 'lib/wurk/sorted_entry.rb', line 16

def parent
  @parent
end

#scoreObject (readonly)

Returns the value of attribute score.



16
17
18
# File 'lib/wurk/sorted_entry.rb', line 16

def score
  @score
end

Instance Method Details

#add_to_queueObject

Removes this entry and re-enqueues it via the client with the payload untouched. Backs the scheduled/dead “add to queue” actions — Sidekiq’s add_to_queue does not touch ‘retry_count`.



52
53
54
55
56
# File 'lib/wurk/sorted_entry.rb', line 52

def add_to_queue
  remove_job do |message|
    Client.new.push(message)
  end
end

#atObject



29
# File 'lib/wurk/sorted_entry.rb', line 29

def at = ::Time.at(score).utc

#deleteObject

Removes this entry from the parent set. Prefers exact-value match (idempotent across duplicates with the same jid), falls back to (score, jid) when constructed without a cached ‘value`.



34
35
36
37
38
39
40
# File 'lib/wurk/sorted_entry.rb', line 34

def delete
  if @value
    @parent.delete_by_value(@parent.name, @value)
  else
    @parent.delete_by_jid(@score, jid)
  end
end

#error?Boolean

Returns:

  • (Boolean)


79
# File 'lib/wurk/sorted_entry.rb', line 79

def error? = !item['error_class'].nil?

#idObject



27
# File 'lib/wurk/sorted_entry.rb', line 27

def id = "#{score}|#{jid}"

#killObject

Removes this entry from its parent set and writes it to the dead set. Death handlers fire with the synthesized “Job killed by API” exception (Sidekiq’s default) so error trackers and the batch death path observe API/UI kills.



73
74
75
76
77
# File 'lib/wurk/sorted_entry.rb', line 73

def kill
  remove_job do |message|
    DeadSet.new.kill(Wurk.dump_json(message))
  end
end

#reschedule(at) ⇒ Object

ZINCRBY to shift the score; positive deltas reschedule into the future. Sidekiq passes the absolute target time; we compute the delta here so the call survives clock skew between caller and Redis.



45
46
47
# File 'lib/wurk/sorted_entry.rb', line 45

def reschedule(at)
  Wurk.redis { |conn| conn.call('ZINCRBY', @parent.name, at.to_f - @score, value) }
end

#retryObject

Same flow but decrements ‘retry_count` first: the count was already incremented when the job entered the retry set, and the next failure bumps it again — without the decrement a manual “Retry now” would consume an attempt. Wire-compat with Sidekiq’s SortedEntry#retry.



62
63
64
65
66
67
# File 'lib/wurk/sorted_entry.rb', line 62

def retry
  remove_job do |message|
    message['retry_count'] = message['retry_count'].to_i - 1 if message['retry_count']
    Client.new.push(message)
  end
end