Module: Plutonium::Wizard::InstanceKey
- Defined in:
- lib/plutonium/wizard/instance_key.rb
Overview
Computes the deterministic identity digest a wizard session row is keyed by (§4). There are two builders, mirroring the two identity axes:
- InstanceKey.concurrency — a wizard with a
concurrency_key. The digest is over the wizard name and the serialized key value(s) (which already include the folded tenant, §4.4). The keyed row IS the lock — two launches with the same key collapse to one digest, so the second resumes the first. - InstanceKey.tokened — a wizard without a
concurrency_key. The digest is over the wizard name and the per-launchwizard_token, so every launch is a fresh, independent (repeatable) run.
The two recipes MUST stay byte-identical between the place that creates rows (runner/driving) and the place that recomputes the key (the gate), or one-time gating silently breaks.
Class Method Summary collapse
-
.concurrency(wizard_name, key_values) ⇒ String
Keyed (concurrency_key) identity.
-
.serialize(value) ⇒ Object
Serialize a key value into a STRUCTURED, unambiguous form for the digest: - Array → each element serialized, kept as a nested array - AR record / GlobalID-able → its GlobalID string - nil → nil (a nil tenant folds to a stable, distinct blank) - scalar → to_s.
-
.tokened(wizard_name, token) ⇒ String
Tokened (no concurrency_key) identity.
Class Method Details
.concurrency(wizard_name, key_values) ⇒ String
Keyed (concurrency_key) identity.
30 31 32 |
# File 'lib/plutonium/wizard/instance_key.rb', line 30 def self.concurrency(wizard_name, key_values) digest("concurrency", wizard_name, serialize(key_values)) end |
.serialize(value) ⇒ Object
Serialize a key value into a STRUCTURED, unambiguous form for the digest:
- Array → each element serialized, kept as a nested array
- AR record / GlobalID-able → its GlobalID string
- nil → nil (a nil tenant folds to a stable, distinct blank)
- scalar → to_s
Structure (not a flat join) is the point: the digest hashes the JSON of the
nested form, so ["a", "b"] and the scalar "a|b" serialize to distinct
JSON (["a","b"] vs "a|b") and can never collide. A separator-joined form
would make a key element containing the separator indistinguishable from a
structural boundary (two distinct runs collapsing to one row — cross-run
data exposure / one-time gating satisfied by the wrong run).
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/plutonium/wizard/instance_key.rb', line 58 def self.serialize(value) case value when Array value.map { |v| serialize(v) } when nil nil when String, Symbol, Numeric, true, false value.to_s else if value.respond_to?(:to_global_id) value.to_global_id.to_s else value.to_s end end end |
.tokened(wizard_name, token) ⇒ String
Tokened (no concurrency_key) identity.
39 40 41 |
# File 'lib/plutonium/wizard/instance_key.rb', line 39 def self.tokened(wizard_name, token) digest("tokened", wizard_name, token.to_s) end |