Class: Wurk::Flow::Status
- Inherits:
-
Object
- Object
- Wurk::Flow::Status
- Defined in:
- lib/wurk/flow/status.rb
Overview
A created flow, read back. The counterpart of Batch::Status, and the only reader of the flow key schema: the dashboard controller and the machine API both go through this, so the two surfaces cannot disagree about what state a flow is in.
Everything here is a snapshot taken at construction — the header in one
round trip, the nodes in a second, and only if something asks for them. A
listing walks header fields alone (state, pending, created_at), so
it never pays for a thousand node records it will not render.
The stored job payload is deliberately not among the fields read. It is the largest thing on a node record, it is the one field that carries the caller's own arguments, and neither surface renders it — the node's jid is what addresses the job, and every job-inspection view already exists.
Defined Under Namespace
Classes: Node
Constant Summary collapse
- NODE_FIELDS =
Every node field except
payload. Ordered as Creation writes them, so the two lists read as the same record. %w[index name class queue jid bid state deps dependents remaining pipe error].freeze
- TERMINAL_STATES =
A flow is
runninguntil it is one of the other three.failedis not terminal — retrying a dead node out of the morgue puts the flow back torunning— which is why it is not listed as such anywhere. %w[succeeded abandoned].freeze
Instance Attribute Summary collapse
-
#fid ⇒ Object
readonly
Returns the value of attribute fid.
Instance Method Summary collapse
- #abandoned? ⇒ Boolean
- #abandoned_at ⇒ Object
- #created_at ⇒ Object
-
#data ⇒ Object
JSON-serializable snapshot.
-
#dead_indexes ⇒ Array<Integer>
The nodes the flow is failed because of — whose job reached the morgue, or whose pipe had nothing to carry.
- #depth ⇒ Object
-
#exists? ⇒ Boolean
False when no
flow:<fid>hash exists: a well-formed fid that was never created, or whose retention ran out. - #expiry ⇒ Object
- #failed? ⇒ Boolean
- #failed_at ⇒ Object
- #finished_at ⇒ Object
-
#initialize(fid) ⇒ Status
constructor
A new instance of Status.
-
#nodes ⇒ Array<Node>
Every node, in declaration order.
- #pending ⇒ Object
- #reload! ⇒ Object
- #running? ⇒ Boolean
- #state ⇒ Object
- #succeeded? ⇒ Boolean
-
#succeeded_count ⇒ Integer
Nodes that have succeeded.
-
#terminal? ⇒ Boolean
True when nothing will move this flow again.
- #total ⇒ Object
- #width ⇒ Object
Constructor Details
#initialize(fid) ⇒ Status
Returns a new instance of Status.
34 35 36 37 38 39 |
# File 'lib/wurk/flow/status.rb', line 34 def initialize(fid) raise ArgumentError, 'fid required' if fid.nil? || fid.to_s.empty? @fid = fid.to_s reload! end |
Instance Attribute Details
#fid ⇒ Object (readonly)
Returns the value of attribute fid.
32 33 34 |
# File 'lib/wurk/flow/status.rb', line 32 def fid @fid end |
Instance Method Details
#abandoned? ⇒ Boolean
60 |
# File 'lib/wurk/flow/status.rb', line 60 def abandoned? = state == 'abandoned' |
#abandoned_at ⇒ Object
55 |
# File 'lib/wurk/flow/status.rb', line 55 def abandoned_at = numeric_or_nil(@header['abandoned_at']) |
#created_at ⇒ Object
52 |
# File 'lib/wurk/flow/status.rb', line 52 def created_at = numeric_or_nil(@header['created_at']) |
#data ⇒ Object
JSON-serializable snapshot. Node rows ride inside it because a flow without its nodes is a progress bar — the graph is the thing being asked for, and a second round of requests to assemble it would race the first.
90 91 92 93 94 95 96 97 98 |
# File 'lib/wurk/flow/status.rb', line 90 def data { 'fid' => @fid, 'state' => state, 'total' => total, 'pending' => pending, 'succeeded' => succeeded_count, 'depth' => depth, 'width' => width, 'created_at' => created_at, 'finished_at' => finished_at, 'failed_at' => failed_at, 'abandoned_at' => abandoned_at, 'dead_nodes' => dead_indexes, 'nodes' => nodes.map(&:data) } end |
#dead_indexes ⇒ Array<Integer>
Returns the nodes the flow is failed because of — whose job reached the morgue, or whose pipe had nothing to carry. Empty for a healthy flow, and empty after abandonment, which drops the set along with the node records it points into.
75 76 77 |
# File 'lib/wurk/flow/status.rb', line 75 def dead_indexes @dead_indexes ||= Wurk.redis { |conn| conn.call('SMEMBERS', Keys.flow_dead(@fid)) }.map(&:to_i).sort end |
#depth ⇒ Object
49 |
# File 'lib/wurk/flow/status.rb', line 49 def depth = @header['depth'].to_i |
#exists? ⇒ Boolean
False when no flow:<fid> hash exists: a well-formed fid that was
never created, or whose retention ran out. Abandoning a flow leaves the
record behind on purpose, so an abandoned flow still exists here.
44 |
# File 'lib/wurk/flow/status.rb', line 44 def exists? = !@header.empty? |
#expiry ⇒ Object
51 |
# File 'lib/wurk/flow/status.rb', line 51 def expiry = @header['expiry'].to_i |
#failed? ⇒ Boolean
59 |
# File 'lib/wurk/flow/status.rb', line 59 def failed? = state == 'failed' |
#failed_at ⇒ Object
54 |
# File 'lib/wurk/flow/status.rb', line 54 def failed_at = numeric_or_nil(@header['failed_at']) |
#finished_at ⇒ Object
53 |
# File 'lib/wurk/flow/status.rb', line 53 def finished_at = numeric_or_nil(@header['finished_at']) |
#nodes ⇒ Array<Node>
Returns every node, in declaration order. Empty for an abandoned flow: the kill switch releases the node records, and their absence is the honest reading of "there is nothing left to show".
82 83 84 |
# File 'lib/wurk/flow/status.rb', line 82 def nodes @nodes ||= read_nodes end |
#pending ⇒ Object
48 |
# File 'lib/wurk/flow/status.rb', line 48 def pending = @header['pending'].to_i |
#reload! ⇒ Object
100 101 102 103 104 105 106 |
# File 'lib/wurk/flow/status.rb', line 100 def reload! raw = Wurk.redis { |conn| conn.call('HGETALL', Keys.flow(@fid)) } @header = raw.is_a?(Hash) ? raw : raw.each_slice(2).to_h @nodes = nil @dead_indexes = nil self end |
#running? ⇒ Boolean
57 |
# File 'lib/wurk/flow/status.rb', line 57 def running? = state == 'running' |
#state ⇒ Object
46 |
# File 'lib/wurk/flow/status.rb', line 46 def state = @header['state'] |
#succeeded? ⇒ Boolean
58 |
# File 'lib/wurk/flow/status.rb', line 58 def succeeded? = state == 'succeeded' |
#succeeded_count ⇒ Integer
Returns nodes that have succeeded. Derived rather than
stored: pending is the counter the completion script decrements,
and a second field for its complement is a second thing to keep true.
69 |
# File 'lib/wurk/flow/status.rb', line 69 def succeeded_count = total - pending |
#terminal? ⇒ Boolean
Returns true when nothing will move this flow again. A failed flow can still recover, so it is not one of these.
64 |
# File 'lib/wurk/flow/status.rb', line 64 def terminal? = TERMINAL_STATES.include?(state) |
#total ⇒ Object
47 |
# File 'lib/wurk/flow/status.rb', line 47 def total = @header['total'].to_i |
#width ⇒ Object
50 |
# File 'lib/wurk/flow/status.rb', line 50 def width = @header['width'].to_i |