process_settings 0.15.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +27 -1
- data/bin/combine_process_settings +31 -8
- data/bin/diff_process_settings +1 -4
- data/lib/process_settings/abstract_monitor.rb +0 -4
- data/lib/process_settings/file_monitor.rb +24 -1
- data/lib/process_settings/helpers/watchdog.rb +37 -0
- data/lib/process_settings/monitor.rb +1 -1
- data/lib/process_settings/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aab773e1074ed3b357a5938e9366b56e69bdc6e36ace59835fdea8bbbe49516d
|
4
|
+
data.tar.gz: 3fe8bb70b1e59498420c878abb86cf2e1b0289694e4ed941a0a11b1a6abc5bce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 939389ccdfaf3fb4880251e34abc36f15e11963ef1ce69e102208a04e084df0c870eeb906103f9859d6ce7af1e27938d713e153ab16768ee6bbaf0e6c6bb5262
|
7
|
+
data.tar.gz: bf6190c8812f0fcb73507bfc4b1cda3e2f9370e5c398df8cdbda2a112a23c80479dcf7189d8fb157ae4725b3bcfafe9bef1bb23a63a27eb3351b33d6644e2d04
|
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.
|
@@ -181,7 +207,7 @@ require 'process_settings/testing/helpers'
|
|
181
207
|
RSpec.configure do |config|
|
182
208
|
# ...
|
183
209
|
|
184
|
-
include ProcessSettings::Testing::RSpec::Helpers
|
210
|
+
config.include ProcessSettings::Testing::RSpec::Helpers
|
185
211
|
|
186
212
|
# Note: the include above will automatically register a global after block that will reset process_settings to their initial values.
|
187
213
|
# ...
|
@@ -92,6 +92,26 @@ def warn_if_old_libyaml_version
|
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
|
+
def settings_files_match?(filename_1, filename_2)
|
96
|
+
filename_1 && filename_2 &&
|
97
|
+
File.exist?(filename_1) && File.exist?(filename_2) &&
|
98
|
+
diff_process_settings(filename_1, filename_2)
|
99
|
+
end
|
100
|
+
|
101
|
+
def diff_process_settings(filename_1, filename_2)
|
102
|
+
system(<<~EOS)
|
103
|
+
bundle exec diff_process_settings --silent "#{filename_1}" "#{filename_2}"
|
104
|
+
EOS
|
105
|
+
status_code = $?.exitstatus
|
106
|
+
case status_code
|
107
|
+
when 0
|
108
|
+
true
|
109
|
+
when 1
|
110
|
+
false
|
111
|
+
else
|
112
|
+
raise "diff_process_settings failed with code #{status_code}"
|
113
|
+
end
|
114
|
+
end
|
95
115
|
|
96
116
|
#
|
97
117
|
# main
|
@@ -115,14 +135,17 @@ tmp_output_filename = "#{output_filename}.tmp"
|
|
115
135
|
system("rm -f #{tmp_output_filename}")
|
116
136
|
File.write(tmp_output_filename, yaml_with_warning_comment)
|
117
137
|
|
118
|
-
|
119
|
-
if
|
120
|
-
|
121
|
-
|
138
|
+
if settings_files_match?(options.initial_filename, tmp_output_filename)
|
139
|
+
if settings_files_match?(output_filename, tmp_output_filename)
|
140
|
+
puts "#{options.root_folder}: unchanged" if options.verbose
|
141
|
+
FileUtils.rm_f(tmp_output_filename)
|
122
142
|
else
|
123
|
-
|
124
|
-
mv
|
125
|
-
|
126
|
-
|
143
|
+
puts "#{options.root_folder}: UPDATING (changed now)" if options.verbose
|
144
|
+
FileUtils.mv(tmp_output_filename, output_filename)
|
145
|
+
end
|
146
|
+
else
|
147
|
+
puts "#{options.root_folder}: UPDATING (unchanged now, but changed from initial)" if options.verbose
|
148
|
+
FileUtils.mv(tmp_output_filename, output_filename)
|
149
|
+
end
|
127
150
|
|
128
151
|
exit(0)
|
data/bin/diff_process_settings
CHANGED
@@ -133,15 +133,11 @@ module ProcessSettings
|
|
133
133
|
|
134
134
|
def full_context_from_cache(dynamic_context)
|
135
135
|
if (full_context = full_context_cache[dynamic_context])
|
136
|
-
logger.info("cache hit ...")
|
137
136
|
full_context
|
138
137
|
else
|
139
|
-
logger.info("cache miss ...")
|
140
138
|
dynamic_context.deep_merge(static_context).tap do |full_context|
|
141
139
|
if full_context_cache.size <= 1000
|
142
140
|
full_context_cache[dynamic_context] = full_context
|
143
|
-
else
|
144
|
-
logger.info("cache limit reached ...")
|
145
141
|
end
|
146
142
|
end
|
147
143
|
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 :
|
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
|
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')
|
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.
|
4
|
+
version: 0.18.0
|
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
|