process_settings 0.15.1 → 0.19.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 37586770d262584d6b5f6b2b4a8a7824eb351d9da15d6577dc0591223c0074f0
4
- data.tar.gz: 8c61aa64d76749381c1311f7c08f2778a0c99134778c09d45aebd32d1ca10ff5
3
+ metadata.gz: de51169a9cf26a44ceb6b123fcd2aadef73f8303b0fc3e0fb704b284b6f00b58
4
+ data.tar.gz: 307e88409813d063891eb8e6015fd0d208b17d7280cf561d97300fbfb1f0b8dc
5
5
  SHA512:
6
- metadata.gz: 212169ce11e8ce4c15f056ffc14c15de1e46fadbc93878c922a577b44217bc8c84d3ecfa49773580bbbf06bdae4cb9a58caf55e570c334282e14ed26c9045ff6
7
- data.tar.gz: 7afc6259634fba9c6a8e0ebe63ab4ffa361c79fdfb5dde63d4f39168222cb790cfa706989e43eaee5ea7b0f9625d393f4411b673bff68e11e0e609c694372adc
6
+ metadata.gz: cb53b7565b37fae70ca9509b42dcc15fbab8ffa03122392b9fb780f8b721dc9c6eb33ba0844525d82b038328afd368d764ac16748e5313234824991f78942c1b
7
+ data.tar.gz: ed9ac91c42392da4f26f01fb732a72b0cf7321b4ba6843dd0ada7cf022ed6eeded1457f0efec377a50a1182442b12aa5ce8a112f2124c871970345620a7461aa
data/README.md CHANGED
@@ -167,6 +167,32 @@ This will be applied in any process that has (`service_name == "frontend"` OR `s
167
167
  ### Precedence
168
168
  The settings YAML files are always combined in alphabetical order by file path. Later settings take precedence over the earlier ones.
169
169
 
170
+ ### Forked Processes
171
+ When using `ProcessSettings` within an environment that is forking threads (like `unicorn` web servers), you can restart the `FileMonitor`
172
+ after the fork with `restart_after_fork`.
173
+ ```ruby
174
+ # unicorn.rb
175
+
176
+ preload_app true
177
+
178
+ after_fork do
179
+ ProcessSettings.instance.restart_after_fork
180
+ end
181
+ ```
182
+
183
+ ### Start Watchdog
184
+ When using `ProcessSettings` you can start a watchdog thread using `start_watchdog_thread` on a particular file path. The watchdog will poll once a minute to double-check if any changes have been missed due to a bug in the `listen` gem or the supporting OS drivers like `inotify`.
185
+ You may not start the watchdog thread it has already been started.
186
+ ```ruby
187
+ ProcessSettings.instance.start_watchdog_thread(file_path)
188
+ ```
189
+
190
+ ### Stop Watchdog
191
+ When using `ProcessSettings` you can stop a watchdog thread using `stop_watchdog_thread`. Once stopped you may start a new watchdog thread.
192
+ ```ruby
193
+ ProcessSettings.instance.stop_watchdog_thread
194
+ ```
195
+
170
196
  ### Testing
171
197
  For testing, it is often necessary to set a specific override hash for the process_settings values to use in
172
198
  that use case. The `ProcessSettings::Testing::RSpec::Helpers` and `ProcessSettings::Testing::Minitest::Helpers` modules are provided for this purpose.
@@ -114,7 +114,11 @@ module ProcessSettings
114
114
  # find last value from matching targets
115
115
  if target_and_settings.target.target_key_matches?(full_context)
116
116
  if (value = target_and_settings.settings.json_doc.mine(*path, not_found_value: :not_found)) != :not_found
117
- latest_result = value
117
+ latest_result = if latest_result.is_a?(Hash) && value.is_a?(Hash)
118
+ latest_result.deep_merge(value)
119
+ else
120
+ value
121
+ end
118
122
  end
119
123
  end
120
124
  latest_result
@@ -133,15 +137,11 @@ module ProcessSettings
133
137
 
134
138
  def full_context_from_cache(dynamic_context)
135
139
  if (full_context = full_context_cache[dynamic_context])
136
- logger.info("cache hit ...")
137
140
  full_context
138
141
  else
139
- logger.info("cache miss ...")
140
142
  dynamic_context.deep_merge(static_context).tap do |full_context|
141
143
  if full_context_cache.size <= 1000
142
144
  full_context_cache[dynamic_context] = full_context
143
- else
144
- logger.info("cache limit reached ...")
145
145
  end
146
146
  end
147
147
  end
@@ -8,6 +8,7 @@ require 'active_support/deprecation'
8
8
  require 'process_settings/abstract_monitor'
9
9
  require 'process_settings/targeted_settings'
10
10
  require 'process_settings/hash_path'
11
+ require 'process_settings/helpers/watchdog'
11
12
 
12
13
  module ProcessSettings
13
14
  class FileMonitor < AbstractMonitor
@@ -24,10 +25,32 @@ module ProcessSettings
24
25
  start_internal(enable_listen_thread?(environment))
25
26
  end
26
27
 
28
+ def start_watchdog_thread(file_path)
29
+ @watchdog_thread and raise ArgumentError, "watchdog thread already running!"
30
+ @watchdog_thread = Thread.new do
31
+ watchdog = Watchdog.new(file_path)
32
+ loop do
33
+ sleep(1.minute)
34
+ watchdog.check
35
+ rescue => ex
36
+ logger.error("ProcessSettings::Watchdog thread: #{ex.class.name}: #{ex.message}")
37
+ end
38
+ end
39
+ end
40
+
41
+ def stop_watchdog_thread
42
+ @watchdog_thread&.kill
43
+ @watchdog_thread = nil
44
+ end
45
+
27
46
  def start
28
47
  start_internal(enable_listen_thread?)
29
48
  end
30
- deprecate :start, deprecator: ActiveSupport::Deprecation.new('1.0', 'ProcessSettings') # will become private
49
+ deprecate start: :restart_after_fork, deprecator: ActiveSupport::Deprecation.new('1.0', 'ProcessSettings')
50
+
51
+ def restart_after_fork
52
+ start_internal(enable_listen_thread?)
53
+ end
31
54
 
32
55
  def listen_thread_running?
33
56
  !@listener.nil?
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/numeric/time'
4
+
5
+ module ProcessSettings
6
+ class Watchdog
7
+ class OutOfSync < StandardError; end
8
+
9
+ MAX_MTIME_DIFFERENCE = 2.minutes
10
+
11
+ def initialize(process_settings_file_path)
12
+ @process_settings_file_path = process_settings_file_path or raise ArgumentError, "process_settings_file_path must be passed"
13
+ end
14
+
15
+ def check
16
+ if version_from_memory != version_from_disk && (Time.now - mtime_from_disk) > MAX_MTIME_DIFFERENCE
17
+ raise ProcessSettings::OutOfSync.new("ProcessSettings versions are out of sync!\n Version from Disk: #{version_from_disk}\n Version from Memory: #{version_from_memory}\n mtime of file: #{mtime_from_disk}")
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :process_settings_file_path
24
+
25
+ def version_from_memory
26
+ ProcessSettings.instance.untargeted_settings.version
27
+ end
28
+
29
+ def version_from_disk
30
+ ProcessSettings::TargetedSettings.from_file(process_settings_file_path, only_meta: true).version
31
+ end
32
+
33
+ def mtime_from_disk
34
+ File.mtime(process_settings_file_path)
35
+ end
36
+ end
37
+ end
@@ -46,7 +46,7 @@ module ProcessSettings
46
46
  def logger=(new_logger)
47
47
  ActiveSupport::Deprecation.warn("ProcessSettings::Monitor.logger is deprecated and will be removed in v1.0.")
48
48
  @logger = new_logger
49
- Listen.logger ||= new_logger
49
+ Listen.logger = new_logger unless Listen.instance_variable_get(:@logger)
50
50
  end
51
51
 
52
52
  deprecate :logger, :logger=, :file_path, :file_path=, deprecator: ActiveSupport::Deprecation.new('1.0', 'ProcessSettings')
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ProcessSettings
4
- VERSION = '0.15.1'
4
+ VERSION = '0.19.0.pre.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: process_settings
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.1
4
+ version: 0.19.0.pre.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Invoca
@@ -94,6 +94,7 @@ files:
94
94
  - lib/process_settings/file_monitor.rb
95
95
  - lib/process_settings/hash_path.rb
96
96
  - lib/process_settings/hash_with_hash_path.rb
97
+ - lib/process_settings/helpers/watchdog.rb
97
98
  - lib/process_settings/monitor.rb
98
99
  - lib/process_settings/replace_versioned_file.rb
99
100
  - lib/process_settings/settings.rb
@@ -122,9 +123,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
122
123
  version: '0'
123
124
  required_rubygems_version: !ruby/object:Gem::Requirement
124
125
  requirements:
125
- - - ">="
126
+ - - ">"
126
127
  - !ruby/object:Gem::Version
127
- version: '0'
128
+ version: 1.3.1
128
129
  requirements: []
129
130
  rubygems_version: 3.0.3
130
131
  signing_key: