Class: Smplkit::ConfigRegistrationBuffer

Inherits:
Object
  • Object
show all
Defined in:
lib/smplkit/buffers.rb

Overview

Thread-safe batch buffer for config declarations.

Configs differ from flags/loggers because each entry carries a nested items dict that grows incrementally as the customer’s code touches more typed getters on a declared handle. The buffer therefore stores per-config metadata permanently (so post-flush deltas can be re-attributed to the right service/environment) and dedups items per (config_id, item_key) so we never re-send an item that the server has already accepted.

Call sites:

  • declare once per client.config.bind(id, …).

  • add_item for every introspected leaf field, or anything else the runtime client observes. Repeated calls with the same (config_id, item_key) after a successful flush are no-ops.

  • drain returns the pending payload list, clears the pending buffer, and records what was sent.

The buffer never drops metadata — only pending is cleared on flush. If the customer’s code declares new items via typed getters after a flush, a fresh pending entry is created using the stored metadata so the server can route the delta to the right source row.

Instance Method Summary collapse

Constructor Details

#initializeConfigRegistrationBuffer

Returns a new instance of ConfigRegistrationBuffer.



135
136
137
138
139
140
# File 'lib/smplkit/buffers.rb', line 135

def initialize
  @pending = {}    # config_id -> { id:, items: {}, ...meta }
  @meta = {}       # config_id -> { service:, environment:, parent:, name:, description: }
  @sent_items = {} # "#{config_id}::#{item_key}" -> true
  @lock = Mutex.new
end

Instance Method Details

#add_item(config_id, item_key, item_type, default, description = nil) ⇒ Object

Queue an item declaration if not already sent.

Must be preceded by declare for the same config_id; otherwise the call is dropped (no implicit declaration).



159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/smplkit/buffers.rb', line 159

def add_item(config_id, item_key, item_type, default, description = nil)
  @lock.synchronize do
    next unless @meta.key?(config_id)
    next if @sent_items.key?("#{config_id}::#{item_key}")

    entry = (@pending[config_id] ||= build_entry(config_id))
    next if entry["items"].key?(item_key)

    item = { "value" => default, "type" => item_type }
    item["description"] = description unless description.nil?
    entry["items"][item_key] = item
  end
end

#declare(config_id, service:, environment:, parent: nil, name: nil, description: nil) ⇒ Object

Register a configuration. Idempotent within a process.



143
144
145
146
147
148
149
150
151
152
153
# File 'lib/smplkit/buffers.rb', line 143

def declare(config_id, service:, environment:, parent: nil, name: nil, description: nil)
  @lock.synchronize do
    next if @meta.key?(config_id)

    @meta[config_id] = {
      service: service, environment: environment,
      parent: parent, name: name, description: description
    }
    @pending[config_id] = build_entry(config_id)
  end
end

#drainObject

Return and clear the pending batch; record sent items.



174
175
176
177
178
179
180
181
182
183
# File 'lib/smplkit/buffers.rb', line 174

def drain
  @lock.synchronize do
    entries = @pending.values
    entries.each do |entry|
      entry["items"].each_key { |item_key| @sent_items["#{entry["id"]}::#{item_key}"] = true }
    end
    @pending = {}
    entries
  end
end

#pending_countObject



185
186
187
# File 'lib/smplkit/buffers.rb', line 185

def pending_count
  @lock.synchronize { @pending.size }
end