service_skeleton 2.0.0 → 2.0.1
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/.github/workflows/ci.yml +25 -27
- data/.gitignore +0 -7
- data/lib/service_skeleton/generator.rb +1 -1
- data/lib/service_skeleton/ultravisor_loggerstash.rb +9 -1
- data/service_skeleton.gemspec +3 -3
- data/ultravisor/lib/ultravisor/child.rb +8 -4
- data/ultravisor/spec/spec_helper.rb +4 -0
- data/ultravisor/spec/ultravisor/child/spawn_spec.rb +112 -3
- metadata +16 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49be65e767a3910dc054f9409a24ab558181c008549582d139f46db04f4a83b1
|
4
|
+
data.tar.gz: 68fd00df7f28da4ae55e3fe19f4935c109646b2873b3ea1f28b6f0d7d7af6942
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c26d8944cbdb9ff40eba5fd7fb4b1f8098f0bbfcb7946712b969a897c7b9fdeb7612e44be5d03603d7e7c11f67ec6389db200e92fef2b323d2f49631e14b994
|
7
|
+
data.tar.gz: f41813b872ad1308b47c1444ec9e6441ea17a8f7dc68a5e865e7d08b08784cfb35d573e38de4799dfa43ab542e09d58f8bb3127e95b7c9dc08123e0497ea7179
|
data/.github/workflows/ci.yml
CHANGED
@@ -1,52 +1,50 @@
|
|
1
|
-
name:
|
1
|
+
name: CI
|
2
2
|
|
3
3
|
on:
|
4
4
|
pull_request:
|
5
5
|
push:
|
6
6
|
branches:
|
7
7
|
- master
|
8
|
-
|
9
|
-
- v*
|
8
|
+
- main
|
10
9
|
|
11
10
|
jobs:
|
12
11
|
build:
|
13
12
|
runs-on: ubuntu-latest
|
14
|
-
|
13
|
+
|
15
14
|
strategy:
|
16
15
|
matrix:
|
17
|
-
ruby:
|
16
|
+
ruby:
|
17
|
+
- 2.5
|
18
|
+
- 2.6
|
19
|
+
- 2.7
|
20
|
+
- 3.0
|
21
|
+
|
18
22
|
steps:
|
19
23
|
- uses: actions/checkout@v2
|
20
|
-
|
21
|
-
|
22
|
-
|
24
|
+
|
25
|
+
- name: Setup ruby
|
26
|
+
uses: ruby/setup-ruby@v1
|
23
27
|
with:
|
24
28
|
ruby-version: ${{ matrix.ruby }}
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
path: vendor/bundle
|
29
|
-
key: ${{ runner.os }}-${{ matrix.ruby }}-gems-${{ hashFiles('**/Gemfile.lock') }}
|
30
|
-
restore-keys: |
|
31
|
-
${{ runner.os }}-${{ matrix.ruby }}-gems-
|
32
|
-
- name: Setup gems
|
33
|
-
run: |
|
34
|
-
gem install bundler
|
35
|
-
bundle config path vendor/bundle
|
36
|
-
bundle install --jobs 4
|
37
|
-
- name: Rubocop
|
29
|
+
bundler-cache: true
|
30
|
+
|
31
|
+
- name: Lint
|
38
32
|
run: bundle exec rubocop
|
33
|
+
|
39
34
|
- name: Tests
|
40
|
-
run: bundle exec
|
41
|
-
|
42
|
-
run: bundle exec rspec ultravisor/spec
|
35
|
+
run: bundle exec rake test
|
36
|
+
|
43
37
|
publish:
|
44
|
-
if:
|
38
|
+
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
|
45
39
|
needs: build
|
46
40
|
runs-on: ubuntu-latest
|
41
|
+
|
47
42
|
steps:
|
48
43
|
- uses: actions/checkout@v2
|
44
|
+
|
49
45
|
- name: Release Gem
|
50
|
-
uses: discourse/publish-rubygems-action@
|
46
|
+
uses: discourse/publish-rubygems-action@v2-beta
|
51
47
|
env:
|
52
|
-
RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_API_KEY}}
|
48
|
+
RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
|
49
|
+
GIT_EMAIL: team@discourse.org
|
50
|
+
GIT_NAME: discoursebot
|
data/.gitignore
CHANGED
@@ -16,8 +16,8 @@ module ServiceSkeleton
|
|
16
16
|
module Generator
|
17
17
|
def generate(config:, metrics_registry:, service_metrics:, service_signal_handlers:)
|
18
18
|
Ultravisor.new(logger: config.logger).tap do |ultravisor|
|
19
|
-
initialize_metrics(ultravisor, config, metrics_registry, service_metrics)
|
20
19
|
initialize_loggerstash(ultravisor, config, metrics_registry)
|
20
|
+
initialize_metrics(ultravisor, config, metrics_registry, service_metrics)
|
21
21
|
initialize_signals(ultravisor, config, service_signal_handlers, metrics_registry)
|
22
22
|
end
|
23
23
|
end
|
@@ -4,8 +4,16 @@ module ServiceSkeleton
|
|
4
4
|
module UltravisorLoggerstash
|
5
5
|
def logstash_writer
|
6
6
|
#:nocov:
|
7
|
-
@ultravisor[:logstash_writer].unsafe_instance
|
7
|
+
@ultravisor[:logstash_writer].unsafe_instance(wait: false)
|
8
8
|
#:nocov:
|
9
9
|
end
|
10
|
+
|
11
|
+
# logstash_writer will be nil if the logstash_writer worker is not running
|
12
|
+
# Ultravisor's restart policy ensures this will never happen at runtime. But
|
13
|
+
# it does happen during startup and shutdown. In this case, we want to skip
|
14
|
+
# writing to logstash, not block forever. STDOUT logging will continue.
|
15
|
+
def loggerstash_log_message(*args)
|
16
|
+
super if !logstash_writer.nil?
|
17
|
+
end
|
10
18
|
end
|
11
19
|
end
|
data/service_skeleton.gemspec
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "service_skeleton"
|
5
5
|
|
6
|
-
s.version = '2.0.
|
6
|
+
s.version = '2.0.1'
|
7
7
|
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
|
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
|
|
30
30
|
s.add_runtime_dependency "prometheus-client", "~> 2.0"
|
31
31
|
s.add_runtime_dependency "sigdump", "~> 0.2"
|
32
32
|
s.add_runtime_dependency "to_regexp", "~> 0.2"
|
33
|
+
s.add_runtime_dependency "webrick"
|
33
34
|
|
34
35
|
s.add_development_dependency 'bundler'
|
35
36
|
s.add_development_dependency 'guard-rspec'
|
@@ -38,8 +39,7 @@ Gem::Specification.new do |s|
|
|
38
39
|
s.add_development_dependency 'rake'
|
39
40
|
s.add_development_dependency 'redcarpet'
|
40
41
|
s.add_development_dependency 'rspec'
|
41
|
-
s.add_development_dependency 'rubocop'
|
42
|
-
s.add_development_dependency 'rubocop-discourse'
|
42
|
+
s.add_development_dependency 'rubocop-discourse', '~> 2.4.1'
|
43
43
|
s.add_development_dependency 'simplecov'
|
44
44
|
s.add_development_dependency 'yard'
|
45
45
|
end
|
@@ -185,13 +185,13 @@ class Ultravisor
|
|
185
185
|
!!(@restart == :always || (@restart == :on_failure && termination_exception))
|
186
186
|
end
|
187
187
|
|
188
|
-
def unsafe_instance
|
188
|
+
def unsafe_instance(wait: true)
|
189
189
|
unless @access == :unsafe
|
190
190
|
raise Ultravisor::ThreadSafetyError,
|
191
191
|
"#unsafe_instance called on a child not declared with access: :unsafe"
|
192
192
|
end
|
193
193
|
|
194
|
-
current_instance
|
194
|
+
current_instance(wait: wait)
|
195
195
|
end
|
196
196
|
|
197
197
|
def cast
|
@@ -381,6 +381,10 @@ class Ultravisor
|
|
381
381
|
# urgh.
|
382
382
|
if @klass.instance_method(:initialize).arity == 0
|
383
383
|
@klass.new()
|
384
|
+
elsif @args.is_a?(Hash)
|
385
|
+
@klass.new(**@args)
|
386
|
+
elsif @args.last.is_a?(Hash)
|
387
|
+
@klass.new(*@args[0...-1], **@args.last)
|
384
388
|
else
|
385
389
|
@klass.new(*@args)
|
386
390
|
end.tap do |i|
|
@@ -394,9 +398,9 @@ class Ultravisor
|
|
394
398
|
end
|
395
399
|
end
|
396
400
|
|
397
|
-
def current_instance
|
401
|
+
def current_instance(wait: true)
|
398
402
|
@spawn_m.synchronize do
|
399
|
-
while @instance.nil?
|
403
|
+
while wait && @instance.nil?
|
400
404
|
@spawn_cv.wait(@spawn_m)
|
401
405
|
end
|
402
406
|
|
@@ -93,14 +93,123 @@ describe Ultravisor::Child do
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
context "with a worker class that takes args" do
|
96
|
+
context "with a worker class that takes only non-keyword args" do
|
97
|
+
let(:args) { { id: :testy, klass: mock_class, args: ["foo", "bar"], method: :run } }
|
98
|
+
let(:mock_class) do
|
99
|
+
Class.new do
|
100
|
+
def initialize(foo, bar)
|
101
|
+
end
|
102
|
+
|
103
|
+
def run
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it "creates the class instance with args" do
|
109
|
+
allow(mock_class).to receive(:new).and_call_original
|
110
|
+
|
111
|
+
child.spawn(term_queue).wait
|
112
|
+
expect(mock_class).to have_received(:new).with("foo", "bar")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context "with a worker class that takes non-keyword and optional args" do
|
97
117
|
let(:args) { { id: :testy, klass: mock_class, args: ["foo", "bar", baz: "wombat"], method: :run } }
|
98
|
-
let(:mock_class)
|
118
|
+
let(:mock_class) do
|
119
|
+
Class.new do
|
120
|
+
def initialize(foo, bar, baz = {})
|
121
|
+
end
|
122
|
+
|
123
|
+
def run
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
99
127
|
|
100
128
|
it "creates the class instance with args" do
|
101
|
-
|
129
|
+
allow(mock_class).to receive(:new).and_call_original
|
102
130
|
|
103
131
|
child.spawn(term_queue).wait
|
132
|
+
expect(mock_class).to have_received(:new).with("foo", "bar", { baz: "wombat" })
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context "with a worker class that takes mixed args" do
|
137
|
+
let(:args) { { id: :testy, klass: mock_class, args: ["foo", "bar", baz: "wombat"], method: :run } }
|
138
|
+
let(:mock_class) do
|
139
|
+
Class.new do
|
140
|
+
def initialize(foo, bar, baz:)
|
141
|
+
end
|
142
|
+
|
143
|
+
def run
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
it "creates the class instance with args" do
|
149
|
+
allow(mock_class).to receive(:new).and_call_original
|
150
|
+
|
151
|
+
child.spawn(term_queue).wait
|
152
|
+
expect(mock_class).to have_received(:new).with("foo", "bar", baz: "wombat")
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context "with a worker class that takes keyword args" do
|
157
|
+
let(:args) { { id: :testy, klass: mock_class, args: [foo: "bar", baz: "wombat"], method: :run } }
|
158
|
+
let(:mock_class) do
|
159
|
+
Class.new do
|
160
|
+
def initialize(foo:, baz:)
|
161
|
+
end
|
162
|
+
|
163
|
+
def run
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
it "creates the class instance with args" do
|
169
|
+
allow(mock_class).to receive(:new).and_call_original
|
170
|
+
|
171
|
+
child.spawn(term_queue).wait
|
172
|
+
expect(mock_class).to have_received(:new).with(foo: "bar", baz: "wombat")
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
context "with a worker class that takes optional args" do
|
177
|
+
let(:args) { { id: :testy, klass: mock_class, args: [foo: "bar", baz: "wombat", fib: "wib", woop: "woob"], method: :run } }
|
178
|
+
let(:mock_class) do
|
179
|
+
Class.new do
|
180
|
+
def initialize(foo:, baz:, fib: "none", woop: nil)
|
181
|
+
end
|
182
|
+
|
183
|
+
def run
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
it "creates the class instance with args" do
|
189
|
+
allow(mock_class).to receive(:new).and_call_original
|
190
|
+
child.spawn(term_queue).wait
|
191
|
+
|
192
|
+
expect(mock_class).to have_received(:new).with(foo: "bar", baz: "wombat", fib: "wib", woop: "woob")
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
context "with a worker class that takes keyword args in form of a hash" do
|
197
|
+
let(:args) { { id: :testy, klass: mock_class, args: { foo: "bar", baz: "wombat" }, method: :run } }
|
198
|
+
let(:mock_class) do
|
199
|
+
Class.new do
|
200
|
+
def initialize(foo:, baz:)
|
201
|
+
end
|
202
|
+
|
203
|
+
def run
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
it "creates the class instance with args" do
|
209
|
+
allow(mock_class).to receive(:new).and_call_original
|
210
|
+
child.spawn(term_queue).wait
|
211
|
+
|
212
|
+
expect(mock_class).to have_received(:new).with(foo: "bar", baz: "wombat")
|
104
213
|
end
|
105
214
|
end
|
106
215
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: service_skeleton
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Palmer
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-03-
|
12
|
+
date: 2021-03-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: frankenstein
|
@@ -82,13 +82,13 @@ dependencies:
|
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '0.2'
|
84
84
|
- !ruby/object:Gem::Dependency
|
85
|
-
name:
|
85
|
+
name: webrick
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
88
|
- - ">="
|
89
89
|
- !ruby/object:Gem::Version
|
90
90
|
version: '0'
|
91
|
-
type: :
|
91
|
+
type: :runtime
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
@@ -96,7 +96,7 @@ dependencies:
|
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
version: '0'
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
|
-
name:
|
99
|
+
name: bundler
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
102
|
- - ">="
|
@@ -110,7 +110,7 @@ dependencies:
|
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
version: '0'
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
|
-
name: guard-
|
113
|
+
name: guard-rspec
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
115
115
|
requirements:
|
116
116
|
- - ">="
|
@@ -124,7 +124,7 @@ dependencies:
|
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '0'
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
|
-
name:
|
127
|
+
name: guard-rubocop
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
129
129
|
requirements:
|
130
130
|
- - ">="
|
@@ -138,7 +138,7 @@ dependencies:
|
|
138
138
|
- !ruby/object:Gem::Version
|
139
139
|
version: '0'
|
140
140
|
- !ruby/object:Gem::Dependency
|
141
|
-
name:
|
141
|
+
name: rack-test
|
142
142
|
requirement: !ruby/object:Gem::Requirement
|
143
143
|
requirements:
|
144
144
|
- - ">="
|
@@ -152,7 +152,7 @@ dependencies:
|
|
152
152
|
- !ruby/object:Gem::Version
|
153
153
|
version: '0'
|
154
154
|
- !ruby/object:Gem::Dependency
|
155
|
-
name:
|
155
|
+
name: rake
|
156
156
|
requirement: !ruby/object:Gem::Requirement
|
157
157
|
requirements:
|
158
158
|
- - ">="
|
@@ -166,7 +166,7 @@ dependencies:
|
|
166
166
|
- !ruby/object:Gem::Version
|
167
167
|
version: '0'
|
168
168
|
- !ruby/object:Gem::Dependency
|
169
|
-
name:
|
169
|
+
name: redcarpet
|
170
170
|
requirement: !ruby/object:Gem::Requirement
|
171
171
|
requirements:
|
172
172
|
- - ">="
|
@@ -180,7 +180,7 @@ dependencies:
|
|
180
180
|
- !ruby/object:Gem::Version
|
181
181
|
version: '0'
|
182
182
|
- !ruby/object:Gem::Dependency
|
183
|
-
name:
|
183
|
+
name: rspec
|
184
184
|
requirement: !ruby/object:Gem::Requirement
|
185
185
|
requirements:
|
186
186
|
- - ">="
|
@@ -197,16 +197,16 @@ dependencies:
|
|
197
197
|
name: rubocop-discourse
|
198
198
|
requirement: !ruby/object:Gem::Requirement
|
199
199
|
requirements:
|
200
|
-
- - "
|
200
|
+
- - "~>"
|
201
201
|
- !ruby/object:Gem::Version
|
202
|
-
version:
|
202
|
+
version: 2.4.1
|
203
203
|
type: :development
|
204
204
|
prerelease: false
|
205
205
|
version_requirements: !ruby/object:Gem::Requirement
|
206
206
|
requirements:
|
207
|
-
- - "
|
207
|
+
- - "~>"
|
208
208
|
- !ruby/object:Gem::Version
|
209
|
-
version:
|
209
|
+
version: 2.4.1
|
210
210
|
- !ruby/object:Gem::Dependency
|
211
211
|
name: simplecov
|
212
212
|
requirement: !ruby/object:Gem::Requirement
|
@@ -334,7 +334,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
334
334
|
- !ruby/object:Gem::Version
|
335
335
|
version: '0'
|
336
336
|
requirements: []
|
337
|
-
rubygems_version: 3.
|
337
|
+
rubygems_version: 3.1.4
|
338
338
|
signing_key:
|
339
339
|
specification_version: 4
|
340
340
|
summary: The bare bones of a service
|