Class: Stoplight::Wiring::LightBuilder Private

Inherits:
Object
  • Object
show all
Defined in:
lib/stoplight/wiring/light_builder.rb,
sig/_private/stoplight/wiring/light_builder.rbs

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Constructs a fully-wired Light instance from validated configuration.

LightBuilder is the final assembly step in the Light creation pipeline. It receives validated config and dependencies from ConfigurationPipeline and wires together all infrastructure components (data stores, trackers, strategies) needed for a functioning circuit breaker.

LightBuilder maintains a global registry (MEMORY_REGISTRY) that ensures the same Memory data store config object always produces the same data store instance:

data_store = Stoplight::DataStore::Memory.new
light1 = Stoplight("foo", data_store: data_store)
light2 = Stoplight("bar", data_store: data_store)
# light1 and light2 share the same underlying memory store

light3 = Stoplight("baz", data_store: Stoplight::DataStore::Memory.new)
# light3 has its own independent store

This singleton behavior is keyed by config object identity (object_id), not by value equality.

Direct Known Subclasses

System::LightBuilder

Constant Summary collapse

FAILOVER_DATA_STORE_CONFIG =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Stoplight::DataStore::Memory.new
MEMORY_REGISTRY =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Returns:

Concurrent::Map.new

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config:, factory:) ⇒ LightBuilder

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of LightBuilder.

Parameters:



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/stoplight/wiring/light_builder.rb', line 37

def initialize(config:, factory:)
  @clock = Infrastructure::SystemClock.new
  @config = config
  @name = T.must(config.name)
  @cool_off_time = config.cool_off_time

  @data_store_config = config.data_store
  @error_notifier = config.error_notifier
  @factory = factory
  @notifiers = config.notifiers
  @traffic_recovery = config.traffic_recovery
  @traffic_control = config.traffic_control

  @error_tracking_policy = Domain::ErrorTrackingPolicy.new(
    tracked: config.tracked_errors,
    skipped: config.skipped_errors
  )
end

Instance Attribute Details

#clockDomain::_Clock (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:



72
73
74
# File 'lib/stoplight/wiring/light_builder.rb', line 72

def clock
  @clock
end

#configDomain::Config (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:



75
76
77
# File 'lib/stoplight/wiring/light_builder.rb', line 75

def config
  @config
end

#data_store_configdata_store (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:



69
70
71
# File 'lib/stoplight/wiring/light_builder.rb', line 69

def data_store_config
  @data_store_config
end

#error_notifiererror_notifier (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:



70
71
72
# File 'lib/stoplight/wiring/light_builder.rb', line 70

def error_notifier
  @error_notifier
end

#factoryDomain::_LightFactory (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



71
72
73
# File 'lib/stoplight/wiring/light_builder.rb', line 71

def factory
  @factory
end

#traffic_controlDomain::_TrafficControl (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



73
74
75
# File 'lib/stoplight/wiring/light_builder.rb', line 73

def traffic_control
  @traffic_control
end

#traffic_recoveryDomain::_TrafficRecovery (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



74
75
76
# File 'lib/stoplight/wiring/light_builder.rb', line 74

def traffic_recovery
  @traffic_recovery
end

Instance Method Details

#buildDomain::Light

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:



56
57
58
59
60
61
62
63
64
65
# File 'lib/stoplight/wiring/light_builder.rb', line 56

def build
  Stoplight::Domain::Light.new(
    @name,
    state_store:,
    green_run_strategy:,
    yellow_run_strategy:,
    red_run_strategy:,
    factory:
  )
end

#create_data_store(data_store_config) ⇒ Domain::_DataStore

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Parameters:

Returns:



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/stoplight/wiring/light_builder.rb', line 159

def create_data_store(data_store_config)
  case data_store_config
  when Stoplight::DataStore::Memory
    memory_registry.compute_if_absent(data_store_config.object_id) do
      Infrastructure::Memory::DataStore.new(
        recovery_lock_store: memory_recovery_lock_store,
        clock:
      )
    end
  when Stoplight::DataStore::Redis
    Infrastructure::FailSafe::DataStore.new(
      data_store: Stoplight::Infrastructure::Redis::DataStore.new(
        clock:,
        redis: data_store_config.redis,
        warn_on_clock_skew: data_store_config.warn_on_clock_skew,
        recovery_lock_store: redis_recovery_lock_store,
        scripting:
      ),
      error_notifier:,
      failover_data_store:,
      circuit_breaker: Stoplight.system_light("data_store:fail_safe:redis")
    )
  else
    raise NoMatchingPatternError, data_store_config
  end
end

#data_storeDomain::_DataStore

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:



104
105
106
# File 'lib/stoplight/wiring/light_builder.rb', line 104

def data_store
  create_data_store(data_store_config)
end

#failover_data_storeDomain::_DataStore

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:



100
101
102
# File 'lib/stoplight/wiring/light_builder.rb', line 100

def failover_data_store
  create_data_store(FAILOVER_DATA_STORE_CONFIG)
end

#green_run_strategyDomain::Strategies::GreenRunStrategy

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



134
135
136
137
138
139
# File 'lib/stoplight/wiring/light_builder.rb', line 134

def green_run_strategy
  Domain::Strategies::GreenRunStrategy.new(
    error_tracking_policy: @error_tracking_policy,
    request_tracker:
  )
end

#memory_recovery_lock_storeInfrastructure::Memory::DataStore::RecoveryLockStore

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



96
97
98
# File 'lib/stoplight/wiring/light_builder.rb', line 96

def memory_recovery_lock_store
  Infrastructure::Memory::DataStore::RecoveryLockStore.new
end

#memory_registryConcurrent::Map[Integer, Infrastructure::Memory::DataStore]

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:



195
# File 'lib/stoplight/wiring/light_builder.rb', line 195

def memory_registry = MEMORY_REGISTRY

#metrics_storeDomain::_MetricsStore

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



108
109
110
# File 'lib/stoplight/wiring/light_builder.rb', line 108

def metrics_store
  Stoplight::Infrastructure::Storage::CompatibilityMetrics.new(config:, data_store:)
end

#notifiers<Stoplight::Notifier::Base>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



80
81
82
83
84
# File 'lib/stoplight/wiring/light_builder.rb', line 80

def notifiers
  Array(@notifiers).map do |notifier|
    Infrastructure::Notifier::FailSafe.new(notifier:, error_notifier:)
  end
end

#recovery_lock_storeDomain::_RecoveryLockStore

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



112
113
114
# File 'lib/stoplight/wiring/light_builder.rb', line 112

def recovery_lock_store
  Stoplight::Infrastructure::Storage::CompatibilityRecoveryLock.new(config:, data_store:)
end

#recovery_metrics_storeDomain::_MetricsStore

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



130
131
132
# File 'lib/stoplight/wiring/light_builder.rb', line 130

def recovery_metrics_store
  Stoplight::Infrastructure::Storage::CompatibilityRecoveryMetrics.new(config:, data_store:)
end

#recovery_probe_trackerDomain::Tracker::RecoveryProbe

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



120
121
122
123
124
125
126
127
128
# File 'lib/stoplight/wiring/light_builder.rb', line 120

def recovery_probe_tracker
  Domain::Tracker::RecoveryProbe.new(
    traffic_recovery:,
    notifiers:,
    config:,
    metrics_store: recovery_metrics_store,
    state_store:
  )
end

#red_run_strategyDomain::Strategies::RedRunStrategy

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



155
156
157
# File 'lib/stoplight/wiring/light_builder.rb', line 155

def red_run_strategy
  Domain::Strategies::RedRunStrategy.new(name: @name, cool_off_time: @cool_off_time)
end

#redisredis

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:



186
187
188
189
190
191
192
193
# File 'lib/stoplight/wiring/light_builder.rb', line 186

def redis
  case data_store_config
  when DataStore::Redis
    data_store_config.redis
  else
    raise TypeError, "Expected Stoplight::DataStore::Redis, got #{data_store_config.class}"
  end
end

#redis_recovery_lock_storeInfrastructure::Redis::DataStore::RecoveryLockStore

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



86
87
88
89
90
91
92
# File 'lib/stoplight/wiring/light_builder.rb', line 86

def redis_recovery_lock_store
  Infrastructure::Redis::DataStore::RecoveryLockStore.new(
    redis:,
    lock_timeout: config.cool_off_time_in_milliseconds,
    scripting:
  )
end

#request_trackerDomain::Tracker::Request

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



116
117
118
# File 'lib/stoplight/wiring/light_builder.rb', line 116

def request_tracker
  Domain::Tracker::Request.new(traffic_control:, notifiers:, config:, metrics_store:, state_store:)
end

#scriptingInfrastructure::Redis::DataStore::Scripting

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



94
# File 'lib/stoplight/wiring/light_builder.rb', line 94

def scripting = Infrastructure::Redis::DataStore::Scripting.new(redis:)

#state_storeDomain::_StateStore

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:



77
# File 'lib/stoplight/wiring/light_builder.rb', line 77

def state_store = Stoplight::Infrastructure::Storage::CompatibilityState.new(config:, data_store:)

#yellow_run_strategyDomain::Strategies::YellowRunStrategy

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/stoplight/wiring/light_builder.rb', line 141

def yellow_run_strategy
  Domain::Strategies::YellowRunStrategy.new(
    name: @name,
    error_tracking_policy: @error_tracking_policy,
    notifiers:,
    request_tracker: recovery_probe_tracker,
    red_run_strategy:,
    state_store:,
    metrics_store:,
    recovery_lock_store:,
    config: @config
  )
end