Module: TIMEx::Registry

Extended by:
Registry
Included in:
Registry
Defined in:
lib/timex/registry.rb

Overview

Copy-on-write registry of named strategies.

Reads are lock-free against the frozen backing hash; writes synchronize and replace the hash atomically. Suited for boot-time registration and per-call resolution on the hot path.

Instance Method Summary collapse

Instance Method Details

#default_selector(&block) ⇒ Proc?

Installs or returns the optional default-strategy selector block.

Yield Returns:

  • (Symbol, nil)

    strategy key to resolve, or nil to fall through to config

Returns:

  • (Proc, nil)

    current selector when called without a block



92
93
94
95
96
97
98
99
100
# File 'lib/timex/registry.rb', line 92

def default_selector(&block)
  if block
    @write_mutex.synchronize do
      @default_selector = block
      invalidate_default_cache
    end
  end
  @default_selector
end

#fetch(name) ⇒ #call

Parameters:

  • name (Symbol, String)

Returns:

Raises:



38
39
40
41
42
43
44
45
# File 'lib/timex/registry.rb', line 38

def fetch(name)
  sym = name.to_sym
  strategies = @strategies
  strategies.fetch(sym) do
    raise StrategyNotFoundError, "no strategy registered as #{name.inspect}; " \
                                 "available: #{strategies.keys.inspect}"
  end
end

#knownArray<Symbol>

Returns known registration keys (snapshot).

Returns:

  • (Array<Symbol>)

    known registration keys (snapshot)



48
49
50
# File 'lib/timex/registry.rb', line 48

def known
  @strategies.keys
end

#register(name, strategy) ⇒ void

This method returns an undefined value.

Parameters:

  • name (Symbol, String)

    registration key

  • strategy (#call)

    callable strategy object

Raises:

  • (ArgumentError)

    when strategy does not respond to #call



26
27
28
29
30
31
32
33
# File 'lib/timex/registry.rb', line 26

def register(name, strategy)
  raise ArgumentError, "strategy must respond to :call, got #{strategy.inspect}" unless strategy.respond_to?(:call)

  @write_mutex.synchronize do
    @strategies = @strategies.merge(name.to_sym => strategy).freeze
    invalidate_default_cache
  end
end

#resolve(strategy_or_name) ⇒ #call?

Resolves a symbol to a registered strategy; passes callables through; nil stays nil.

Parameters:

  • strategy_or_name (Symbol, #call, nil)

Returns:

Raises:



57
58
59
60
61
62
63
# File 'lib/timex/registry.rb', line 57

def resolve(strategy_or_name)
  case strategy_or_name
  when Symbol then fetch(strategy_or_name)
  when nil then nil
  else strategy_or_name
  end
end

#resolve_for_call(strategy) ⇒ #call

Resolves the callable used by TIMEx#deadline: the configured default when strategy is nil, a registered entry when it is a Symbol, otherwise the object must respond to #call (strategy class or instance).

Parameters:

  • strategy (Symbol, #call, nil)

Returns:

Raises:

  • (StrategyNotFoundError)

    when strategy names an unknown registration

  • (ArgumentError)

    when strategy is neither nil, a Symbol, nor +#call+-able



73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/timex/registry.rb', line 73

def resolve_for_call(strategy)
  case strategy
  when nil then select_default
  when Symbol then fetch(strategy)
  else
    if strategy.respond_to?(:call)
      strategy
    else
      raise ArgumentError,
        "strategy must be a Symbol, Class, or instance responding to " \
        "#call, got #{strategy.inspect}"
    end
  end
end

#select_default#call

Note:

Hot path: caches static Configuration#default_strategy resolutions; a configured selector disables the cache because results may vary per call.

Resolves TIMEx.config default strategy with optional selector and caching.

Returns:



108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/timex/registry.rb', line 108

def select_default
  if @default_selector
    sym = @default_selector.call
    return fetch(sym) if sym
  end

  key = TIMEx.config.default_strategy
  return @cached_default if key == @cached_default_key && @cached_default

  resolved = fetch(key)
  @cached_default_key = key
  @cached_default = resolved
  resolved
end