Module: Wurk::Fetcher::PrivateListKey
- Defined in:
- lib/wurk/fetcher/private_list_key.rb
Overview
Reads the owner back out of a reliable-fetch private list key
(queue:<public>|<host>|<pid>|<nonce>|<idx>, see
Reliable.private_queue_name) for the Reaper's liveness check. Pure string
work, no Redis.
Constant Summary collapse
- NONCE_PATTERN =
The nonce shape Component::PROCESS_NONCE writes (
SecureRandom.hex(6)). /\A[0-9a-f]{12}\z/
Class Method Summary collapse
- .integer?(str) ⇒ Boolean
-
.narrow_tail(parts) ⇒ Object
<host>|<pid>|<idx>— written before the nonce existed. - .nonce?(str) ⇒ Boolean
-
.owner_tails(parts) ⇒ Object
Owner segments of a private-list key, taken from the right, as [host, pid, nonce, segment_count] readings in preference order (empty when nothing parses).
-
.parse_full(key) ⇒ Object
queue:<public>|<host>|<pid>|<nonce>|<idx>→ [public_q, host, pid, nonce], parsed from the right so a|inside the queue name is tolerated. -
.wide_tail(parts) ⇒ Object
<host>|<pid>|<nonce>|<idx>— the shape every current process writes.
Class Method Details
.integer?(str) ⇒ Boolean
69 70 71 |
# File 'lib/wurk/fetcher/private_list_key.rb', line 69 def integer?(str) str.is_a?(String) && str.match?(/\A\d+\z/) end |
.narrow_tail(parts) ⇒ Object
<host>|<pid>|<idx> — written before the nonce existed. Such a list can
still hold a pre-upgrade process's in-flight jobs across a rolling
upgrade, so it stays reclaimable even though nothing writes it anymore.
65 66 67 |
# File 'lib/wurk/fetcher/private_list_key.rb', line 65 def narrow_tail(parts) [parts[-3], parts[-2].to_i, nil, 3] if integer?(parts[-2]) end |
.nonce?(str) ⇒ Boolean
73 74 75 |
# File 'lib/wurk/fetcher/private_list_key.rb', line 73 def nonce?(str) str.is_a?(String) && str.match?(NONCE_PATTERN) end |
.owner_tails(parts) ⇒ Object
Owner segments of a private-list key, taken from the right, as [host, pid, nonce, segment_count] readings in preference order (empty when nothing parses). The wide shape is preferred: an all-digit nonce is rare but reachable, and reading such a key narrow would take the pid for the host and the nonce for the pid — draining a live owner's list out from under it.
47 48 49 50 51 |
# File 'lib/wurk/fetcher/private_list_key.rb', line 47 def owner_tails(parts) return [] unless parts.size >= 3 && integer?(parts[-1]) [wide_tail(parts), narrow_tail(parts)].compact end |
.parse_full(key) ⇒ Object
queue:<public>|<host>|<pid>|<nonce>|<idx> → [public_q, host, pid,
nonce], parsed from the right so a | inside the queue name is
tolerated. nil when the key isn't a well-formed private list.
With no known prefix to split on, both owner shapes are tried in
preference order and the first one leaving a real public queue behind
wins. The narrow reading is what saves a pre-nonce key from an all-digit
host (queue:q|123456789012|<pid>|<idx> — a bare Docker hostname is 12
hex chars): read wide, its host segment either eats the whole queue
name (plain queue — nothing left over) or truncates it at the first
pipe and puts the real pid in the nonce slot (pipe-bearing queue).
Both misreads are refused: the leftover must be a real queue name and
the pseudo-nonce must be nonce-shaped (see wide_tail).
30 31 32 33 34 35 36 37 38 39 |
# File 'lib/wurk/fetcher/private_list_key.rb', line 30 def parse_full(key) parts = key.split('|') owner_tails(parts).each do |host, pid, nonce, width| public_q = parts[0...-width].join('|') next unless public_q.start_with?(Keys::QUEUE_PREFIX) && public_q != Keys::QUEUE_PREFIX return [public_q, host, pid, nonce] end nil end |
.wide_tail(parts) ⇒ Object
<host>|<pid>|<nonce>|<idx> — the shape every current process writes.
The nonce slot must carry PROCESS_NONCE's exact shape (NONCE_PATTERN):
on a pre-nonce key read wide it holds the real pid, which is never 12
hex, so the guard is what falls such a key through to narrow_tail
instead of misreading it.
58 59 60 |
# File 'lib/wurk/fetcher/private_list_key.rb', line 58 def wide_tail(parts) [parts[-4], parts[-3].to_i, parts[-2], 4] if parts.size >= 4 && integer?(parts[-3]) && nonce?(parts[-2]) end |