Class: Takagi::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/takagi/config.rb,
sig/takagi/config.rbs

Overview

Stores runtime configuration loaded from YAML or manual overrides.

Defined Under Namespace

Classes: AllocationConfig, PluginConfig

Constant Summary collapse

Observability =

Returns:

  • (Object)
EventBusConfig =

Returns:

  • (Object)
RouterConfig =

Returns:

  • (Object)
MiddlewareConfig =

Returns:

  • (Object)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeConfig

Returns a new instance of Config.



24
25
26
27
28
29
30
31
32
33
34
# File 'lib/takagi/config.rb', line 24

def initialize
  set_server_defaults
  set_observability_defaults
  set_event_bus_defaults
  set_router_defaults
  set_middleware_defaults
  set_allocation_defaults
  set_plugin_defaults
  @custom = {}
  @server_name = nil
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) {|arg0| ... } ⇒ Object

Parameters:

  • name (Object)
  • args (Object)

Yields:

Yield Parameters:

  • arg0

Yield Returns:

  • (Object)

Returns:

  • (Object)


44
45
46
47
48
49
50
51
52
53
# File 'lib/takagi/config.rb', line 44

def method_missing(name, *args, &block)
  key = name.to_s.chomp('=').to_sym
  if name.to_s.end_with?('=')
    @custom[key] = args.first
  elsif @custom.key?(key)
    @custom[key]
  else
    super(&block)
  end
end

Instance Attribute Details

#allocationObject

Returns the value of attribute allocation.



21
22
23
# File 'lib/takagi/config.rb', line 21

def allocation
  @allocation
end

#auto_migrateObject

Returns the value of attribute auto_migrate.

Returns:

  • (Object)


21
22
23
# File 'lib/takagi/config.rb', line 21

def auto_migrate
  @auto_migrate
end

#bind_addressObject

Returns the value of attribute bind_address.

Returns:

  • (Object)


21
22
23
# File 'lib/takagi/config.rb', line 21

def bind_address
  @bind_address
end

#customObject

Returns the value of attribute custom.

Returns:

  • (Object)


21
22
23
# File 'lib/takagi/config.rb', line 21

def custom
  @custom
end

#event_busObject

Returns the value of attribute event_bus.

Returns:

  • (Object)


21
22
23
# File 'lib/takagi/config.rb', line 21

def event_bus
  @event_bus
end

#loggerObject

Returns the value of attribute logger.

Returns:

  • (Object)


21
22
23
# File 'lib/takagi/config.rb', line 21

def logger
  @logger
end

#middlewareObject

Returns the value of attribute middleware.

Returns:

  • (Object)


21
22
23
# File 'lib/takagi/config.rb', line 21

def middleware
  @middleware
end

#observabilityObject

Returns the value of attribute observability.

Returns:

  • (Object)


21
22
23
# File 'lib/takagi/config.rb', line 21

def observability
  @observability
end

#pluginsObject

Returns the value of attribute plugins.



21
22
23
# File 'lib/takagi/config.rb', line 21

def plugins
  @plugins
end

#portObject

Returns the value of attribute port.

Returns:

  • (Object)


21
22
23
# File 'lib/takagi/config.rb', line 21

def port
  @port
end

#processesObject

Returns the value of attribute processes.

Returns:

  • (Object)


21
22
23
# File 'lib/takagi/config.rb', line 21

def processes
  @processes
end

#protocolsObject

Returns the value of attribute protocols.

Returns:

  • (Object)


21
22
23
# File 'lib/takagi/config.rb', line 21

def protocols
  @protocols
end

#routerObject

Returns the value of attribute router.

Returns:

  • (Object)


21
22
23
# File 'lib/takagi/config.rb', line 21

def router
  @router
end

#server_nameObject

Returns the value of attribute server_name.

Returns:

  • (Object)


21
22
23
# File 'lib/takagi/config.rb', line 21

def server_name
  @server_name
end

#threadsObject

Returns the value of attribute threads.

Returns:

  • (Object)


21
22
23
# File 'lib/takagi/config.rb', line 21

def threads
  @threads
end

Instance Method Details

#[](key) ⇒ Object

Parameters:

  • key (Object)

Returns:

  • (Object)


36
37
38
# File 'lib/takagi/config.rb', line 36

def [](key)
  @custom[key.to_sym]
end

#[]=(key, value) ⇒ Object

Parameters:

  • key (Object)
  • value (Object)

Returns:

  • (Object)


40
41
42
# File 'lib/takagi/config.rb', line 40

def []=(key, value)
  @custom[key.to_sym] = value
end

#apply_basic_settings(data) ⇒ Object

Parameters:

  • data (Object)

Returns:

  • (Object)


76
77
78
79
80
81
82
83
# File 'lib/takagi/config.rb', line 76

def apply_basic_settings(data)
  assign_setting(data, 'port') { |value| @port = value }
  assign_setting(data, 'bind_address') { |value| @bind_address = value }
  assign_processes(data)
  assign_setting(data, 'threads') { |value| @threads = value }
  assign_protocols(data['protocols'])
  assign_setting(data, 'server_name') { |value| @server_name = value }
end

#apply_custom_settings(data) ⇒ Object

Parameters:

  • data (Object)

Returns:

  • (Object)


173
174
175
176
# File 'lib/takagi/config.rb', line 173

def apply_custom_settings(data)
  custom_settings = data['custom'] || {}
  custom_settings.each { |key, value| self[key] = value }
end

#apply_event_bus(data) ⇒ nil, untyped

Parameters:

  • data (Object)

Returns:

  • (nil, untyped)


102
103
104
105
106
107
108
# File 'lib/takagi/config.rb', line 102

def apply_event_bus(data)
  event_bus_data = data['event_bus']
  return unless event_bus_data

  assign_event_bus_core(event_bus_data)
  assign_message_buffer_settings(event_bus_data)
end

#apply_logger(data) ⇒ nil, untyped

Parameters:

  • data (Object)

Returns:

  • (nil, untyped)


85
86
87
88
89
90
91
92
# File 'lib/takagi/config.rb', line 85

def apply_logger(data)
  logger_config = data['logger']
  return unless logger_config.is_a?(Hash)

  output = resolve_logger_output(logger_config['output'])
  level = resolve_logger_level(logger_config['level'])
  @logger = Takagi::Logger.new(log_output: output, level: level)
end

#apply_middleware(data) ⇒ nil, untyped

Parameters:

  • data (Object)

Returns:

  • (nil, untyped)


119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/takagi/config.rb', line 119

def apply_middleware(data)
  middleware_data = data['middleware']
  return unless middleware_data

  # Enable/disable middleware globally
  @middleware.enabled = middleware_data['enabled'] if middleware_data.key?('enabled')

  # Load middleware stack from config
  return unless middleware_data['stack']

  @middleware.stack = middleware_data['stack'].map do |middleware_config|
    parse_middleware_entry(middleware_config)
  end
end

#apply_observability(data) ⇒ nil, untyped

Parameters:

  • data (Object)

Returns:

  • (nil, untyped)


94
95
96
97
98
99
100
# File 'lib/takagi/config.rb', line 94

def apply_observability(data)
  observability = data['observability']
  return unless observability

  backends = Array(observability['backends']).map(&:to_sym)
  @observability.backends = backends if backends.any?
end

#apply_router(data) ⇒ nil, untyped

Parameters:

  • data (Object)

Returns:

  • (nil, untyped)


110
111
112
113
114
115
116
117
# File 'lib/takagi/config.rb', line 110

def apply_router(data)
  router_data = data['router']
  return unless router_data

  return unless router_data['default_content_format']

  @router.default_content_format = router_data['default_content_format']
end

#assign_event_bus_core(event_bus_data) ⇒ Object

Parameters:

  • event_bus_data (Object)

Returns:

  • (Object)


287
288
289
290
291
# File 'lib/takagi/config.rb', line 287

def assign_event_bus_core(event_bus_data)
  %w[ractors async_threads process_pool_size state_cache_size state_cache_ttl cleanup_interval max_observer_age].each do |key|
    assign_event_bus_setting(event_bus_data, key)
  end
end

#assign_event_bus_setting(event_bus_data, key) ⇒ nil, untyped

Parameters:

  • event_bus_data (Object)
  • key (Object)

Returns:

  • (nil, untyped)


300
301
302
303
304
305
# File 'lib/takagi/config.rb', line 300

def assign_event_bus_setting(event_bus_data, key)
  value = event_bus_data[key]
  return if value.nil?

  @event_bus.public_send("#{key}=", value)
end

#assign_message_buffer_settings(event_bus_data) ⇒ Object

Parameters:

  • event_bus_data (Object)

Returns:

  • (Object)


293
294
295
296
297
298
# File 'lib/takagi/config.rb', line 293

def assign_message_buffer_settings(event_bus_data)
  @event_bus.message_buffering_enabled = event_bus_data['message_buffering_enabled'] if event_bus_data.key?('message_buffering_enabled')

  assign_event_bus_setting(event_bus_data, 'message_buffer_max_messages')
  assign_event_bus_setting(event_bus_data, 'message_buffer_ttl')
end

#assign_processes(data) ⇒ nil, untyped

Parameters:

  • data (Object)

Returns:

  • (nil, untyped)


274
275
276
277
278
279
# File 'lib/takagi/config.rb', line 274

def assign_processes(data)
  processes_value = data['processes'] || data['process']
  return unless processes_value

  @processes = processes_value
end

#assign_protocols(protocols) ⇒ nil, untyped

Parameters:

  • protocols (Object)

Returns:

  • (nil, untyped)


281
282
283
284
285
# File 'lib/takagi/config.rb', line 281

def assign_protocols(protocols)
  return unless protocols

  @protocols = Array(protocols).map(&:to_sym)
end

#assign_setting(data, key) {|value| ... } ⇒ nil, untyped

Parameters:

  • data (Object)
  • key (Object)

Yields:

  • (value)

Yield Parameters:

  • arg0 (Object)

Yield Returns:

  • (Object)

Returns:

  • (nil, untyped)


267
268
269
270
271
272
# File 'lib/takagi/config.rb', line 267

def assign_setting(data, key)
  value = data[key]
  return if value.nil?

  yield(value)
end

#default_middleware_stack::Array[{ name: "Debugging", options: ::Hash[untyped, untyped] }]

Default middleware stack Returns an array of middleware configurations

Returns:

  • (::Array[{ name: "Debugging", options: ::Hash[untyped, untyped] }])


331
332
333
334
335
# File 'lib/takagi/config.rb', line 331

def default_middleware_stack
  [
    { name: 'Debugging', options: {} }
  ]
end

#load_file(path) ⇒ Object

Parameters:

  • path (Object)

Returns:

  • (Object)


60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/takagi/config.rb', line 60

def load_file(path)
  data = load_yaml(path)

  apply_basic_settings(data)
  apply_logger(data)
  apply_observability(data)
  apply_event_bus(data)
  apply_router(data)
  apply_middleware(data)
  apply_allocation(data)
  apply_plugins(data)
  apply_custom_settings(data)
end

#load_yaml(path) ⇒ Object

Parameters:

  • path (Object)

Returns:

  • (Object)


178
179
180
181
182
183
184
185
# File 'lib/takagi/config.rb', line 178

def load_yaml(path)
  content = File.read(path)
  YAML.safe_load(
    content,
    permitted_classes: [Symbol],
    aliases: true
  ) || {}
end

#parse_middleware_entry(entry) ⇒ Object

Parse middleware entry from YAML config Supports both simple strings and hash with options

Examples:

Simple string

"Logging"

Hash with options

{ name: "Caching", options: { ttl: 300 } }

Parameters:

  • entry (Object)

Returns:

  • (Object)


315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/takagi/config.rb', line 315

def parse_middleware_entry(entry)
  case entry
  when String
    { name: entry, options: {} }
  when Hash
    {
      name: entry['name'] || entry[:name],
      options: entry['options'] || entry[:options] || {}
    }
  else
    raise ArgumentError, "Invalid middleware entry: #{entry.inspect}"
  end
end

#resolve_logger_level(level) ⇒ Object

Parameters:

  • level (Object)

Returns:

  • (Object)


200
201
202
203
204
205
206
207
# File 'lib/takagi/config.rb', line 200

def resolve_logger_level(level)
  return level if level.is_a?(Integer)
  return ::Logger::INFO unless level

  ::Logger.const_get(level.to_s.upcase)
rescue NameError
  ::Logger::INFO
end

#resolve_logger_output(target) ⇒ Object

Parameters:

  • target (Object)

Returns:

  • (Object)


187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/takagi/config.rb', line 187

def resolve_logger_output(target)
  case target
  when nil, 'stdout'
    $stdout
  when 'stderr'
    $stderr
  else
    File.open(target.to_s, 'a')
  end
rescue StandardError
  $stdout
end

#respond_to_missing?(name, include_private = false) ⇒ Boolean

Parameters:

  • name (Object)
  • include_private (Boolean) (defaults to: false)

Returns:

  • (Boolean)


55
56
57
58
# File 'lib/takagi/config.rb', line 55

def respond_to_missing?(name, include_private = false)
  key = name.to_s.chomp('=').to_sym
  @custom.key?(key) || super
end

#set_event_bus_defaultsObject

Returns:

  • (Object)


225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/takagi/config.rb', line 225

def set_event_bus_defaults
  @event_bus = EventBusConfig.new(
    ractors: 10,
    async_threads: 10,
    process_pool_size: 0,
    state_cache_size: 1000,
    state_cache_ttl: 3600,
    cleanup_interval: 60,
    max_observer_age: 600,
    message_buffering_enabled: false,
    message_buffer_max_messages: 100,
    message_buffer_ttl: 300
  )
end

#set_middleware_defaultsObject

Returns:

  • (Object)


246
247
248
249
250
251
# File 'lib/takagi/config.rb', line 246

def set_middleware_defaults
  @middleware = MiddlewareConfig.new(
    enabled: true,
    stack: default_middleware_stack
  )
end

#set_observability_defaultsObject

Returns:

  • (Object)


221
222
223
# File 'lib/takagi/config.rb', line 221

def set_observability_defaults
  @observability = Observability.new(backends: [:memory])
end

#set_router_defaultsObject

Returns:

  • (Object)


240
241
242
243
244
# File 'lib/takagi/config.rb', line 240

def set_router_defaults
  @router = RouterConfig.new(
    default_content_format: 50 # application/json
  )
end

#set_server_defaultsObject

Returns:

  • (Object)


209
210
211
212
213
214
215
216
217
218
219
# File 'lib/takagi/config.rb', line 209

def set_server_defaults
  @port = 5683
  @bind_address = '0.0.0.0' # Bind to all interfaces by default
  # Production-friendly default: INFO. Set TAKAGI_LOG_LEVEL=DEBUG
  # (or pass a takagi.yml `logger:` block) to see the verbose noise.
  @logger = ::Logger.new($stdout, ::Logger::INFO)
  @auto_migrate = true
  @threads = 1
  @processes = 1
  @protocols = [:udp]
end