process_settings 0.4.0.pre.2 → 0.4.0.pre.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c32d23d7503792ad86bb246e9d6363549a8f2810
4
- data.tar.gz: 55f3900720da5e83839220d36ea1d2528e44b8c1
3
+ metadata.gz: 35f7f59386045aa27ee3134236eed4d9681090b3
4
+ data.tar.gz: b9fa6bdfffe65b11b6858b9826a09dfc8de990bd
5
5
  SHA512:
6
- metadata.gz: c5f38b5e5cd23422e7aa93d5200330d0ffd8d0b0f4bca65195d7c9933a70fa25ef93c86bf8e18f31850463c750074be6e0a37d24f9445898b5f0d4da6e82c0aa
7
- data.tar.gz: 645b3393990436b24173375813347f5cf8af7abcb7c57ee2fbc1c0a5109ea7bd7103fb6495016f979ddc6ed34cc6ee3929c9a8f326b133caa7c68f9c85324869
6
+ metadata.gz: 173134db7642f5e1622b6c640c12b7c4ef3024bc328bf215fe3cc613b71d47651e068c73504f83af546d2c9cd09085d73d8f3878e86e48a3ec215ac3fa8e50ee
7
+ data.tar.gz: 6c910bd0d0372e2c0e41dcd274732dbb3a60e0ac8ad1e9e2998a495c9a438c321c6fc6fba136911ff01416d3e5a6ffbb5db8e71fe091c2800665fcd6d1e6a811
@@ -8,7 +8,7 @@ require 'active_support'
8
8
 
9
9
  module ProcessSettings
10
10
  class Monitor
11
- attr_reader :file_path, :min_polling_seconds
11
+ attr_reader :file_path, :min_polling_seconds, :logger
12
12
  attr_reader :static_context, :untargeted_settings, :statically_targeted_settings
13
13
 
14
14
  DEFAULT_MIN_POLLING_SECONDS = 5
@@ -30,6 +30,8 @@ module ProcessSettings
30
30
  if modified.include?(@file_path)
31
31
  @logger.info("ProcessSettings::Monitor file #{@file_path} changed. Reloading.")
32
32
  load_untargeted_settings
33
+
34
+ load_statically_targeted_settings
33
35
  end
34
36
  end
35
37
 
@@ -37,7 +39,7 @@ module ProcessSettings
37
39
 
38
40
  load_untargeted_settings
39
41
 
40
- statically_targeted_settings # so that notify_on_change will be called if any changes
42
+ load_statically_targeted_settings
41
43
  end
42
44
 
43
45
  # stops listening for changes
@@ -51,30 +53,11 @@ module ProcessSettings
51
53
  @on_change_callbacks << callback
52
54
  end
53
55
 
54
- # Loads the most recent settings from disk and returns them.
55
- def load_untargeted_settings
56
- @untargeted_settings = load_file(file_path)
57
- end
58
-
59
56
  # Assigns a new static context. Recomputes statically_targeted_settings.
60
57
  def static_context=(context)
61
58
  @static_context = context
62
59
 
63
- statically_targeted_settings(force: true)
64
- end
65
-
66
- # Loads the latest untargeted settings from disk. Returns the current process settings as a TargetAndProcessSettings given
67
- # by applying the static context to the current untargeted settings from disk.
68
- # If these have changed, borrows this thread to call notify_on_change.
69
- def statically_targeted_settings(force: false)
70
- if force || @last_untargetted_settings != @untargeted_settings
71
- @statically_targeted_settings = @untargeted_settings.with_static_context(@static_context)
72
- @last_untargetted_settings = @untargeted_settings
73
-
74
- notify_on_change
75
- end
76
-
77
- @statically_targeted_settings
60
+ load_statically_targeted_settings(force_retarget: true)
78
61
  end
79
62
 
80
63
  # Returns the process settings value at the given `path` using the given `dynamic_context`.
@@ -97,6 +80,32 @@ module ProcessSettings
97
80
  end
98
81
  end
99
82
 
83
+ private
84
+
85
+ # Loads the most recent settings from disk
86
+ def load_untargeted_settings
87
+ new_untargeted_settings = load_file(file_path)
88
+ old_version = @untargeted_settings&.version
89
+ new_version = new_untargeted_settings.version
90
+ @untargeted_settings = new_untargeted_settings
91
+ logger.info("ProcessSettings::Monitor#load_untargeted_settings loaded version #{new_version}#{" to replace version #{old_version}" if old_version}")
92
+ end
93
+
94
+ # Loads the latest untargeted settings from disk. Returns the current process settings as a TargetAndProcessSettings given
95
+ # by applying the static context to the current untargeted settings from disk.
96
+ # If these have changed, borrows this thread to call notify_on_change.
97
+ def load_statically_targeted_settings(force_retarget: false)
98
+ if force_retarget || @last_untargetted_settings != @untargeted_settings
99
+ @last_untargetted_settings = @untargeted_settings
100
+ @statically_targeted_settings = @untargeted_settings.with_static_context(@static_context)
101
+ if @last_statically_targetted_settings != @statically_targeted_settings
102
+ @last_statically_targetted_settings = @statically_targeted_settings
103
+
104
+ notify_on_change
105
+ end
106
+ end
107
+ end
108
+
100
109
  class << self
101
110
  attr_accessor :file_path
102
111
  attr_reader :logger
@@ -117,8 +126,9 @@ module ProcessSettings
117
126
  end
118
127
  end
119
128
 
120
- private
121
-
129
+ # Calls all registered on_change callbacks. Rescues any exceptions they may raise.
130
+ # Note: this method can be re-entrant to the class; the on_change callbacks may call right back into these methods.
131
+ # Therefore it's critical to finish all transitions and release any resources before calling this method.
122
132
  def notify_on_change
123
133
  @on_change_callbacks.each do |callback|
124
134
  begin
@@ -5,31 +5,52 @@ require_relative 'targeted_settings'
5
5
  module ProcessSettings
6
6
  # This class will override a file with a higher version file; it accounts for minor version number use
7
7
  module ReplaceVersionedFile
8
+ class SourceVersionOlderError < StandardError; end
9
+ class FileDoesNotExistError < StandardError; end
10
+
8
11
  class << self
12
+ # Contracts
13
+ # source_file_path must be present
14
+ # destination_file_path must be present
15
+ # source_file_path must exist on filesystem
16
+ # source file version cannot be older destination version
9
17
  def replace_file_on_newer_file_version(source_file_path, destination_file_path)
10
18
  source_file_path.to_s == '' and raise ArgumentError, "source_file_path not present"
11
19
  destination_file_path.to_s == '' and raise ArgumentError, "destination_file_path not present"
20
+ File.exist?(source_file_path) or raise FileDoesNotExistError, "source file '#{source_file_path}' does not exist"
21
+ validate_source_version_is_not_older(source_file_path, destination_file_path)
12
22
 
13
23
  if source_version_is_newer?(source_file_path, destination_file_path)
14
24
  FileUtils.mv(source_file_path, destination_file_path)
15
25
  elsif source_file_path != destination_file_path # make sure we're not deleting destination file
16
- if File.exist?(source_file_path)
17
- FileUtils.remove_file(source_file_path) # clean up, remove left over file
18
- end
26
+ FileUtils.rm_f(source_file_path) # clean up, remove left over file
19
27
  end
20
28
  end
21
29
 
22
30
  private
23
31
 
24
32
  def source_version_is_newer?(source_file_path, destination_file_path)
25
- if File.exist?(source_file_path)
26
- if File.exist?(destination_file_path)
27
- source_version = ProcessSettings::TargetedSettings.from_file(source_file_path, only_meta: true).version
28
- destination_version = ProcessSettings::TargetedSettings.from_file(destination_file_path, only_meta: true).version
29
-
30
- Gem::Version.new(source_version) > Gem::Version.new(destination_version)
31
- else
32
- true
33
+ if File.exist?(destination_file_path)
34
+ source_version = ProcessSettings::TargetedSettings.from_file(source_file_path, only_meta: true).version
35
+ destination_version = ProcessSettings::TargetedSettings.from_file(destination_file_path, only_meta: true).version
36
+
37
+ source_version.to_f > destination_version.to_f
38
+ else
39
+ true
40
+ end
41
+ end
42
+
43
+ def validate_source_version_is_not_older(source_file_path, destination_file_path)
44
+ if File.exist?(destination_file_path)
45
+ source_version = ProcessSettings::TargetedSettings.from_file(source_file_path, only_meta: true).version
46
+ destination_version = ProcessSettings::TargetedSettings.from_file(destination_file_path, only_meta: true).version
47
+
48
+ if source_version.to_f < destination_version.to_f
49
+ FileUtils.rm_f(source_file_path) # clean up, remove left over file
50
+
51
+ raise SourceVersionOlderError,
52
+ "source file '#{source_file_path}' is version #{source_version}"\
53
+ " and destination file '#{destination_file_path}' is version #{destination_version}"
33
54
  end
34
55
  end
35
56
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ProcessSettings
4
- VERSION = '0.4.0.pre.2'
4
+ VERSION = '0.4.0.pre.3'
5
5
  end
6
-
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.0.pre.2
4
+ version: 0.4.0.pre.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Invoca