captain_config 1.0.0 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a5493e2fcb8ce58f2bc41f302ea1f4ffddffaa3b5ed47a140a0224e8b684d0ca
4
- data.tar.gz: 1f01c90101896d6703b97fb98d48fce1fb69e8b1640bf1fa372194f9c9cfbecb
3
+ metadata.gz: 0e24dce3bbbadb28e2e3272c6456ef39dc6730ffe403dde2d26d986daf9c699a
4
+ data.tar.gz: 868c2655ca58fb22442b03768ccf089bdc9d6b8cdafa4c059a6eb7490a294c7e
5
5
  SHA512:
6
- metadata.gz: 4877a1a5d325b23775c32fae6b48fd6462781aff286e4b06398d68b81d3f6eae541cd32e7fb5d7f22d5631b6e10e017f4a5a7ad7faf671e932aba803ccc1bdad
7
- data.tar.gz: bf9d708d0e801b2dd39c2b975c06ea674a84be9d7a7317cf2ffde8b95d1159116f5ba496d31d2ba35827a3aa7e64d6445be7039555a16816dad9cae6305fe341
6
+ metadata.gz: e9f3406b4cb80f2a0d4172ae4edbe5f2c728039e70540677a076e7ba358b03c536537764848dea6f3c497fc048444d8deda04759edf44df0fe1d5d8d72f3def5
7
+ data.tar.gz: a4f4d2f3318bd6ceb5c04455792ac70e2d233bb31e763307725528ebc4ec1661c4261e4dbaf275347a8eb50dac6cd234f074e24f4bb5e09f446d1e77feb55309
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # CaptainConfig
2
2
 
3
+ [![Build Status](https://travis-ci.org/dirk/captain_config.svg?branch=master)](https://travis-ci.org/dirk/captain_config)
4
+
3
5
  `CaptainConfig` makes it easy to add developer-friendly configuration to control your application's behavior.
4
6
 
5
7
  ## Getting Started
@@ -18,7 +20,7 @@ bundle exec rails generate captain_config
18
20
 
19
21
  **Not on Rails?** Check out the [template](https://github.com/dirk/captain_config/blob/master/lib/generators/templates/create_captain_configs.rb.tt) for the ActiveRecord migration that would have been generated; that describes how this gem expects that table to look.
20
22
 
21
- Then—assuming you're using Rails—set up some configuration in your config:
23
+ Then—assuming you're using Rails—set up some configuration in your `config/initializers`:
22
24
 
23
25
  ```rb
24
26
  # config/initializers/captain_config.rb
@@ -55,8 +57,39 @@ end
55
57
  <% end >
56
58
  ```
57
59
 
60
+ ### Sidekiq
61
+
62
+ There is a Sidekiq middleware to automatically reload configuration.
63
+
64
+ ```rb
65
+ Sidekiq.configure_server do |config|
66
+ config.server_middleware do |chain|
67
+ chain.add CaptainConfig::SidekiqMiddlewareFactory.build
68
+
69
+ # By default it only reloads every 1 second. Use the `interval:` argument
70
+ # to change this frequency:
71
+ #
72
+ # chain.add CaptainConfig::SidekiqMiddlewareFactory.build(interval: 5.0)
73
+ end
74
+ end
75
+ ```
76
+
58
77
  ## Contributing
59
78
 
79
+ Clone the repo and run `bundle install` to get started developing locally.
80
+
81
+ There are integration specs which set up a sample Rails application and run tests against it. As that takes some time (more than a few seconds), there is a script to run just the non-integration specs:
82
+
83
+ ```sh
84
+ ./script/rspec-without-integration
85
+ ```
86
+
87
+ Arguments are forwarded to RSpec, so if you want to run an individual spec file:
88
+
89
+ ```sh
90
+ ./script/rspec-without-integration spec/captain_config_spec.rb
91
+ ```
92
+
60
93
  Bug reports and pull requests are welcome on [the GitHub repository](https://github.com/dirk/captain_config).
61
94
 
62
95
  ## Code of Conduct
@@ -46,5 +46,6 @@ Gem::Specification.new do |spec|
46
46
  spec.add_development_dependency 'rake', '~> 10.0'
47
47
  spec.add_development_dependency 'rspec', '~> 3.0'
48
48
  spec.add_development_dependency 'sqlite3', '~> 1.3'
49
+ spec.add_development_dependency 'timecop', '~> 0.9'
49
50
  spec.add_development_dependency 'wait_for_it', '~> 0.2'
50
51
  end
@@ -10,6 +10,7 @@ module CaptainConfig
10
10
 
11
11
  autoload_under 'middlewares' do
12
12
  autoload :PumaMiddleware
13
+ autoload :SidekiqMiddlewareFactory
13
14
  end
14
15
 
15
16
  autoload_under 'models' do
@@ -0,0 +1,54 @@
1
+ module CaptainConfig::SidekiqMiddlewareFactory
2
+ # Since Sidekiq calls `.new` on the middleware class for every job we cannot
3
+ # store state in the instance between jobs like we would with a Rack
4
+ # middleware. Therefore we need to build a new class to hold that state.
5
+ #
6
+ # interval: - Minimum time (in seconds) that must pass between reloading
7
+ # configuration.
8
+ def self.build(interval: 1.0)
9
+ klass = Class.new do
10
+ include SidekiqMiddleware
11
+ end
12
+ klass.setup(interval: interval)
13
+ klass
14
+ end
15
+
16
+ module SidekiqMiddleware
17
+ def self.included(klass)
18
+ klass.extend(ClassMethods)
19
+ end
20
+
21
+ module ClassMethods
22
+ attr_reader :interval, :last_loaded_at
23
+
24
+ def setup(interval:)
25
+ @interval = interval
26
+ @mutex = Mutex.new
27
+ @last_loaded_at = Time.at(0)
28
+ end
29
+
30
+ def needs_load?
31
+ (Time.now - @last_loaded_at) >= @interval
32
+ end
33
+
34
+ def load
35
+ @mutex.synchronize do
36
+ # The instances of the middleware on each thread call `#needs_load?`
37
+ # unsynchronized, so they may think a reload is needed when it isn't.
38
+ return unless needs_load?
39
+
40
+ service = CaptainConfig::Service.last_created_service
41
+ service&.load
42
+
43
+ @last_loaded_at = Time.now
44
+ end
45
+ end
46
+ end
47
+
48
+ def call(_worker, _job, _queue)
49
+ self.class.load if self.class.needs_load?
50
+
51
+ yield
52
+ end
53
+ end
54
+ end
@@ -26,6 +26,10 @@ class CaptainConfig::BooleanConfig < CaptainConfig::BaseConfig
26
26
  true
27
27
  when 'false'
28
28
  false
29
+ when true
30
+ true
31
+ when false
32
+ false
29
33
  else
30
34
  raise ArgumentError.new("Cannot coerce value: #{value.inspect}")
31
35
  end
@@ -40,7 +40,7 @@ class CaptainConfig::Service
40
40
  configs.value.fetch key
41
41
  end
42
42
 
43
- def set(key, new_value, coerce: false)
43
+ def set(key, new_value, coerce: true)
44
44
  assert_loaded!
45
45
 
46
46
  record = configured_entries.fetch(key).model.find_or_create_by!(key: key)
@@ -1,3 +1,3 @@
1
1
  module CaptainConfig
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -0,0 +1,2 @@
1
+ #!/bin/sh
2
+ bundle exec rspec --exclude-pattern "spec/integration/**/*" $@
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: captain_config
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dirk Gadsden
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '1.3'
125
+ - !ruby/object:Gem::Dependency
126
+ name: timecop
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.9'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.9'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: wait_for_it
127
141
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +164,7 @@ files:
150
164
  - lib/captain_config.rb
151
165
  - lib/captain_config/configured_entry.rb
152
166
  - lib/captain_config/middlewares/puma_middleware.rb
167
+ - lib/captain_config/middlewares/sidekiq_middleware_factory.rb
153
168
  - lib/captain_config/models/base_config.rb
154
169
  - lib/captain_config/models/boolean_config.rb
155
170
  - lib/captain_config/models/integer_config.rb
@@ -159,6 +174,7 @@ files:
159
174
  - lib/captain_config/version.rb
160
175
  - lib/generators/captain_config_generator.rb
161
176
  - lib/generators/templates/create_captain_configs.rb.tt
177
+ - script/rspec-without-integration
162
178
  homepage: https://github.com/dirk/captain_config
163
179
  licenses: []
164
180
  metadata: