Module: CMDx::StoreKey

Extended by:
StoreKey
Included in:
StoreKey
Defined in:
lib/cmdx/store_key.rb

Overview

Shared store key helpers for store-backed task features (Idempotency, CircuitBreaker, Lock, RateLimit, and others).

#compose joins colon-separated segments, each coerced with CMDx::Stores#key!. #segment resolves a per-invocation suffix from a declaration (symbol, proc, callable, or literal).

Constant Summary collapse

CLASS_KEY =

Resolver for one breaker or limiter per task class (see CircuitBreaker, RateLimit). Not used for segment-required features (Idempotency, Lock).

:class

Instance Method Summary collapse

Instance Method Details

#compose(*segments) ⇒ String

Returns joined key.

Parameters:

Returns:

  • (String) —

    joined key

Raises:

  • (ArgumentError) —

    when any segment is empty after coercion



22
23
24
# File 'lib/cmdx/store_key.rb', line 22

def compose(*segments)
  segments.map! { |s| Stores.key!(s) }.join(":")
end

#segment(task, resolver, skip: nil) ⇒ String?

Resolves a store key segment from a task. Used by Idempotency, CircuitBreaker, and other store-backed declarations.

Parameters:

  • task (Task)
  • resolver (Symbol, String, Proc, #call)
  • skip (Object, nil) (defaults to: nil) —

    when resolver == skip, returns nil without reading context (for example CLASS_KEY)

Returns:

  • (String, nil) —

    non-empty segment, or nil when blank or skipped



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/cmdx/store_key.rb', line 34

def segment(task, resolver, skip: nil)
  return if skip && resolver == skip

  raw =
    case resolver
    when Symbol
      task.context[resolver]
    when Proc
      task.instance_exec(task, &resolver)
    else
      return resolver.call(task) if resolver.respond_to?(:call)

      resolver
    end

  str = raw&.to_s
  str if str && !str.empty?
end

#task_key(task, namespace:, resolver:, class_scoped: false) ⇒ String?

Builds the base store key for a task invocation.

Parameters:

  • task (Task)
  • namespace (String)
  • resolver (Symbol, String, Proc, #call)
  • class_scoped (Boolean) (defaults to: false) —

    when true, CLASS_KEY (:class) resolves to namespace:TaskName without reading context; blank segments for other resolvers return nil instead of raising

Returns:

  • (String, nil) —

    full key, or nil when the segment is blank

See Also:



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/cmdx/store_key.rb', line 64

def task_key(task, namespace:, resolver:, class_scoped: false)
  skip = class_scoped ? CLASS_KEY : nil
  segment_value = segment(task, resolver, skip:)

  if segment_value.nil?
    return compose(namespace, task.class.name) if class_scoped && resolver == CLASS_KEY

    return nil
  end

  compose(namespace, task.class.name, segment_value)
end