Class: ProcessSettings::AbstractMonitor
- Inherits:
-
Object
- Object
- ProcessSettings::AbstractMonitor
- Defined in:
- lib/process_settings/abstract_monitor.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#full_context_cache ⇒ Object
readonly
Returns the value of attribute full_context_cache.
-
#logger ⇒ Object
readonly
Returns the value of attribute logger.
-
#min_polling_seconds ⇒ Object
readonly
Returns the value of attribute min_polling_seconds.
-
#static_context ⇒ Object
Returns the value of attribute static_context.
-
#statically_targeted_settings ⇒ Object
readonly
Returns the value of attribute statically_targeted_settings.
Class Method Summary collapse
Instance Method Summary collapse
-
#[](*path, dynamic_context: {}, required: true) ⇒ Object
This is the main entry point for looking up settings on the Monitor instance.
-
#cancel_when_updated(handle) ⇒ Object
removes the given when_updated block identified by the handle returned from when_updated.
- #full_context_from_cache(dynamic_context) ⇒ Object
-
#initialize(logger:) ⇒ AbstractMonitor
constructor
A new instance of AbstractMonitor.
- #on_change(&callback) ⇒ Object deprecated Deprecated.
-
#targeted_value(*path, dynamic_context:, required: true) ⇒ Object
Returns the process settings value at the given ‘path` using the given `dynamic_context`.
-
#when_updated(initial_update: true, &block) ⇒ Object
Idempotently adds the given block to the when_updated collection calls the block first unless initial_update: false is passed returns a handle (the block itself) which can later be passed into cancel_when_updated.
Constructor Details
#initialize(logger:) ⇒ AbstractMonitor
Returns a new instance of AbstractMonitor.
18 19 20 21 22 23 24 |
# File 'lib/process_settings/abstract_monitor.rb', line 18 def initialize(logger:) @logger = logger or raise ArgumentError, "logger must be not be nil" @on_change_callbacks = [] @when_updated_blocks = Set.new @static_context = {} @full_context_cache = {} end |
Instance Attribute Details
#full_context_cache ⇒ Object (readonly)
Returns the value of attribute full_context_cache.
16 17 18 |
# File 'lib/process_settings/abstract_monitor.rb', line 16 def full_context_cache @full_context_cache end |
#logger ⇒ Object (readonly)
Returns the value of attribute logger.
15 16 17 |
# File 'lib/process_settings/abstract_monitor.rb', line 15 def logger @logger end |
#min_polling_seconds ⇒ Object (readonly)
Returns the value of attribute min_polling_seconds.
15 16 17 |
# File 'lib/process_settings/abstract_monitor.rb', line 15 def min_polling_seconds @min_polling_seconds end |
#static_context ⇒ Object
Returns the value of attribute static_context.
16 17 18 |
# File 'lib/process_settings/abstract_monitor.rb', line 16 def static_context @static_context end |
#statically_targeted_settings ⇒ Object (readonly)
Returns the value of attribute statically_targeted_settings.
16 17 18 |
# File 'lib/process_settings/abstract_monitor.rb', line 16 def statically_targeted_settings @statically_targeted_settings end |
Class Method Details
.ensure_no_symbols(value) ⇒ Object
153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/process_settings/abstract_monitor.rb', line 153 def ensure_no_symbols(value) case value when Symbol raise ArgumentError, "symbol value #{value.inspect} found--should be String" when Hash value.each do |k, v| k.is_a?(Symbol) and raise ArgumentError, "symbol key #{k.inspect} found--should be String" ensure_no_symbols(v) end when Array value.each { |v| ensure_no_symbols(v) } end end |
Instance Method Details
#[](*path, dynamic_context: {}, required: true) ⇒ Object
This is the main entry point for looking up settings on the Monitor instance.
- ‘path’, ‘to’, ‘setting’
-
will return 42 in this example settings YAML:
code
path: to: setting: 42
code
47 48 49 |
# File 'lib/process_settings/abstract_monitor.rb', line 47 def [](*path, dynamic_context: {}, required: true) targeted_value(*path, dynamic_context: dynamic_context, required: required) end |
#cancel_when_updated(handle) ⇒ Object
removes the given when_updated block identified by the handle returned from when_updated
69 70 71 |
# File 'lib/process_settings/abstract_monitor.rb', line 69 def cancel_when_updated(handle) @when_updated_blocks.delete_if { |callback| callback.eql?(handle) } end |
#full_context_from_cache(dynamic_context) ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/process_settings/abstract_monitor.rb', line 138 def full_context_from_cache(dynamic_context) if (full_context = full_context_cache[dynamic_context]) full_context else dynamic_context.deep_merge(static_context).tap do |full_context| if full_context_cache.size <= 1000 full_context_cache[dynamic_context] = full_context end end end end |
#on_change(&callback) ⇒ Object
Registers the given callback block to be called when settings change. These are run using the shared thread that monitors for changes so be courteous and don’t monopolize it!
76 77 78 |
# File 'lib/process_settings/abstract_monitor.rb', line 76 def on_change(&callback) @on_change_callbacks << callback end |
#targeted_value(*path, dynamic_context:, required: true) ⇒ Object
Returns the process settings value at the given ‘path` using the given `dynamic_context`. (It is assumed that the static context was already set through static_context=.) If nothing set at the given `path`:
if required, raises SettingsPathNotFound
else returns nil
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/process_settings/abstract_monitor.rb', line 96 def targeted_value(*path, dynamic_context:, required: true) # Merging the static context in is necessary to make sure that the static context isn't shifting # this can be rather costly to do every time if the dynamic context is not changing # Warn in the case where dynamic context was attempting to change a static value changes = dynamic_context.each_with_object({}) do |(key, dynamic_value), result| if static_context.has_key?(key) static_value = static_context[key] if static_value != dynamic_value result[key] = [static_value, dynamic_value] end end end changes.empty? or warn("WARNING: static context overwritten by dynamic!\n#{changes.inspect}") full_context = full_context_from_cache(dynamic_context) result = statically_targeted_settings.reduce(:not_found) do |latest_result, target_and_settings| # find last value from matching targets if target_and_settings.target.target_key_matches?(full_context) if (value = target_and_settings.settings.json_doc.mine(*path, not_found_value: :not_found)) != :not_found latest_result = if latest_result.is_a?(Hash) && value.is_a?(Hash) latest_result.deep_merge(value) else value end end end latest_result end if result == :not_found if required raise SettingsPathNotFound, "no settings found for path #{path.inspect}" else nil end else result end end |
#when_updated(initial_update: true, &block) ⇒ Object
Idempotently adds the given block to the when_updated collection calls the block first unless initial_update: false is passed returns a handle (the block itself) which can later be passed into cancel_when_updated
54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/process_settings/abstract_monitor.rb', line 54 def when_updated(initial_update: true, &block) if @when_updated_blocks.add?(block) if initial_update begin block.call(self) rescue => ex logger.error("ProcessSettings::Monitor#when_updated rescued exception during initialization:\n#{ex.class}: #{ex.}") end end end block end |