captain_config 1.0.0 → 1.1.0

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: 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: