servitium 1.2.20 → 1.3.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/.github/workflows/gem-push.yml +11 -0
- data/.rubocop.yml +14 -0
- data/README.md +63 -1
- data/Rakefile +0 -4
- data/lib/generators/servitium/templates/context.rb +1 -1
- data/lib/servitium/configuration.rb +20 -0
- data/lib/servitium/context.rb +5 -0
- data/lib/servitium/service.rb +45 -4
- data/lib/servitium/{service_job.rb → service_active_job.rb} +1 -7
- data/lib/servitium/service_sidekiq_job.rb +16 -0
- data/lib/servitium/version.rb +1 -1
- data/lib/servitium.rb +18 -1
- data/servitium.gemspec +4 -2
- metadata +43 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fa6706af0892ab90d3f327cac1d97b5e6ed7b0c6e9fa6fa06484058d9733d78a
|
|
4
|
+
data.tar.gz: 0bf72aac0656de3572940cc6a40dbe3952eb406f7895a002994db1ad7987dc84
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 989ad0d166962653b196c3bdee84878b6f7143c8c190a2cddb9f635d65bb5f64e9555978ebc84a54d6f848f930b678f3b6e089cbceef9f60c52c62a408527d0a
|
|
7
|
+
data.tar.gz: aba51072b58ada34593d1d368f18e13d708f72d5f5cc5567cf4b1602d6750f7f52346ac4303aa3d8f7074a35a014875da8dc60f970c76a24ed06d57a70c43bf2
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# https://www.fastruby.io/blog/ruby/code-quality/how-we-use-rubocop-and-standardrb.html
|
|
2
|
+
|
|
3
|
+
require:
|
|
4
|
+
- standard
|
|
5
|
+
|
|
6
|
+
inherit_gem:
|
|
7
|
+
standard: config/base.yml
|
|
8
|
+
|
|
9
|
+
AllCops:
|
|
10
|
+
NewCops: enable
|
|
11
|
+
Exclude:
|
|
12
|
+
- node_modules/**/*
|
|
13
|
+
- public/**/*
|
|
14
|
+
- vendor/**/*
|
data/README.md
CHANGED
|
@@ -48,7 +48,69 @@ Or install it yourself as:
|
|
|
48
48
|
|
|
49
49
|
## Usage
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
You define a context for the service, which describes what goes in and out
|
|
52
|
+
```ruby
|
|
53
|
+
class ExampleContext < ApplicationContext
|
|
54
|
+
attribute :some, type: String, default: "new"
|
|
55
|
+
|
|
56
|
+
validates :some, presence: true
|
|
57
|
+
end
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
You can be very explicit in what goes in our out:
|
|
61
|
+
```ruby
|
|
62
|
+
class ExampleContext < ApplicationContext
|
|
63
|
+
input do
|
|
64
|
+
attribute :some, type: String, default: "new"
|
|
65
|
+
validates :some, presence: true
|
|
66
|
+
end
|
|
67
|
+
output do
|
|
68
|
+
attribute :some, type: String, default: "new"
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
And you define the service itself:
|
|
74
|
+
```ruby
|
|
75
|
+
class ExampleService < ApplicationService
|
|
76
|
+
def perform
|
|
77
|
+
context.some.reverse!
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
You can also include the context in the service, for less complicated services:
|
|
83
|
+
|
|
84
|
+
```ruby
|
|
85
|
+
class ExampleService < ApplicationService
|
|
86
|
+
context do
|
|
87
|
+
attribute :some, type: :string, default: "new"
|
|
88
|
+
end
|
|
89
|
+
def perform
|
|
90
|
+
context.some.reverse!
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Next you use it as follows:
|
|
96
|
+
```ruby
|
|
97
|
+
ExampleService.perform(some: 'test').some # => tset
|
|
98
|
+
```
|
|
99
|
+
A service always returns it context
|
|
100
|
+
|
|
101
|
+
Services can also run in the background:
|
|
102
|
+
```ruby
|
|
103
|
+
ExampleService.perform_later(some: 'test') # => #<ExampleContext>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
You can use the generator to generate service code:
|
|
107
|
+
```
|
|
108
|
+
❯ rails g servitium:service Example
|
|
109
|
+
|
|
110
|
+
create app/services/example_service.rb
|
|
111
|
+
create app/services/example_context.rb
|
|
112
|
+
create test/services/example_service_test.rb
|
|
113
|
+
```
|
|
52
114
|
|
|
53
115
|
## License
|
|
54
116
|
|
data/Rakefile
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Servitium
|
|
4
|
+
class Configuration
|
|
5
|
+
attr_accessor :bg_jobs_platform
|
|
6
|
+
attr_writer :logger,
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
@logger = Logger.new(STDOUT)
|
|
10
|
+
@logger.level = Logger::INFO
|
|
11
|
+
|
|
12
|
+
@bg_jobs_platform = :active_job
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# logger [Object].
|
|
16
|
+
def logger
|
|
17
|
+
@logger.is_a?(Proc) ? instance_exec(&@logger) : @logger
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/servitium/context.rb
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'active_model/naming'
|
|
4
|
+
require 'active_model/translation'
|
|
5
|
+
|
|
3
6
|
module Servitium
|
|
4
7
|
class Context
|
|
5
8
|
extend ActiveModel::Callbacks
|
|
9
|
+
extend ActiveModel::Naming
|
|
10
|
+
extend ActiveModel::Translation
|
|
6
11
|
|
|
7
12
|
include Servitium::ContextModel
|
|
8
13
|
|
data/lib/servitium/service.rb
CHANGED
|
@@ -121,6 +121,14 @@ module Servitium
|
|
|
121
121
|
end
|
|
122
122
|
|
|
123
123
|
class << self
|
|
124
|
+
def perform_async(*args)
|
|
125
|
+
perform_later(*args)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def perform_sync(*args)
|
|
129
|
+
perform(*args)
|
|
130
|
+
end
|
|
131
|
+
|
|
124
132
|
# Main point of entry for services, will raise in case of errors
|
|
125
133
|
def perform!(*args)
|
|
126
134
|
inst = new(*args)
|
|
@@ -147,10 +155,8 @@ module Servitium
|
|
|
147
155
|
# Call the service returning the service instance
|
|
148
156
|
def call(*args)
|
|
149
157
|
inst = new(*args)
|
|
150
|
-
|
|
151
158
|
valid_in = inst.context.valid?
|
|
152
159
|
valid_in &&= inst.context.valid?(:in) if inst.context.class.inbound_scope_used
|
|
153
|
-
|
|
154
160
|
if valid_in
|
|
155
161
|
inst.context.instance_variable_set(:@called, true)
|
|
156
162
|
inst.send(:call)
|
|
@@ -166,18 +172,53 @@ module Servitium
|
|
|
166
172
|
# Perform this service async
|
|
167
173
|
def perform_later(*args)
|
|
168
174
|
inst = new(*args)
|
|
169
|
-
|
|
170
175
|
valid_in = inst.context.valid?
|
|
171
176
|
valid_in &&= inst.context.valid?(:in) if inst.context.class.inbound_scope_used
|
|
172
177
|
|
|
173
178
|
if valid_in
|
|
174
179
|
inst.context.instance_variable_set(:@called, true)
|
|
175
|
-
|
|
180
|
+
|
|
181
|
+
if Servitium.config.bg_jobs_platform == :sidekiq
|
|
182
|
+
formatted_args = JSON.load(JSON.dump(format_args(inst.context.attributes_hash)))
|
|
183
|
+
Servitium::ServiceSidekiqJob.set(queue: name.constantize.queue_name).perform_async(name, formatted_args)
|
|
184
|
+
else
|
|
185
|
+
Servitium::ServiceActiveJob.set(queue: name.constantize.queue_name).perform_later(name, inst.context.attributes_hash)
|
|
186
|
+
end
|
|
176
187
|
end
|
|
177
188
|
|
|
178
189
|
inst.context
|
|
179
190
|
end
|
|
180
191
|
|
|
192
|
+
def format_args(hash)
|
|
193
|
+
hash.transform_values! do |v|
|
|
194
|
+
case v
|
|
195
|
+
when ActiveRecord::Base
|
|
196
|
+
v.id
|
|
197
|
+
when Hash
|
|
198
|
+
format_args(v)
|
|
199
|
+
when Array
|
|
200
|
+
format_array(v)
|
|
201
|
+
else
|
|
202
|
+
v
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def format_array(array)
|
|
208
|
+
array.map do |ele|
|
|
209
|
+
case ele
|
|
210
|
+
when ActiveRecord::Base
|
|
211
|
+
ele.id
|
|
212
|
+
when Hash
|
|
213
|
+
format_args(ele)
|
|
214
|
+
when Array
|
|
215
|
+
format_array(ele)
|
|
216
|
+
else
|
|
217
|
+
ele
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
181
222
|
def queue_name
|
|
182
223
|
'default'
|
|
183
224
|
end
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Servitium
|
|
4
|
-
class
|
|
5
|
-
queue_as { queue_name }
|
|
6
|
-
|
|
4
|
+
class ServiceActiveJob < ActiveJob::Base
|
|
7
5
|
def perform(class_name, *args)
|
|
8
6
|
service = class_name.constantize.call(*args)
|
|
9
7
|
|
|
@@ -13,9 +11,5 @@ module Servitium
|
|
|
13
11
|
service.send(:async_failure)
|
|
14
12
|
end
|
|
15
13
|
end
|
|
16
|
-
|
|
17
|
-
def queue_name
|
|
18
|
-
arguments.first.constantize.queue_name
|
|
19
|
-
end
|
|
20
14
|
end
|
|
21
15
|
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Servitium
|
|
4
|
+
class ServiceSidekiqJob
|
|
5
|
+
include Sidekiq::Job
|
|
6
|
+
def perform(class_name, *args)
|
|
7
|
+
service = class_name.constantize.call(*args)
|
|
8
|
+
|
|
9
|
+
if service.context.success?
|
|
10
|
+
service.send(:async_success)
|
|
11
|
+
else
|
|
12
|
+
service.send(:async_failure)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
data/lib/servitium/version.rb
CHANGED
data/lib/servitium.rb
CHANGED
|
@@ -5,6 +5,7 @@ require 'active_attr'
|
|
|
5
5
|
require 'active_support'
|
|
6
6
|
require 'action_controller'
|
|
7
7
|
require 'active_job'
|
|
8
|
+
require 'sidekiq'
|
|
8
9
|
|
|
9
10
|
require 'servitium/error'
|
|
10
11
|
require 'servitium/context_failure'
|
|
@@ -13,8 +14,24 @@ require 'servitium/sub_contexts'
|
|
|
13
14
|
require 'servitium/scoped_attributes'
|
|
14
15
|
require 'servitium/context_model'
|
|
15
16
|
require 'servitium/context'
|
|
16
|
-
require 'servitium/
|
|
17
|
+
require 'servitium/service_active_job'
|
|
18
|
+
require 'servitium/service_sidekiq_job'
|
|
17
19
|
require 'servitium/service'
|
|
18
20
|
require 'servitium/version'
|
|
21
|
+
require 'servitium/configuration'
|
|
19
22
|
|
|
20
23
|
require 'servitium/rails' if defined?(::Rails)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
module Servitium
|
|
27
|
+
class << self
|
|
28
|
+
def setup
|
|
29
|
+
@config = Configuration.new
|
|
30
|
+
yield config
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def config
|
|
34
|
+
@config ||= Configuration.new
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
data/servitium.gemspec
CHANGED
|
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
|
|
|
26
26
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
27
27
|
spec.require_paths = ['lib']
|
|
28
28
|
|
|
29
|
-
spec.add_dependency 'active_attr', '
|
|
29
|
+
spec.add_dependency 'active_attr', '~> 0.15'
|
|
30
30
|
spec.add_dependency 'activejob', '> 5.1'
|
|
31
31
|
spec.add_dependency 'activemodel', '> 5.1'
|
|
32
32
|
spec.add_dependency 'activerecord', '> 5.1'
|
|
@@ -40,6 +40,8 @@ Gem::Specification.new do |spec|
|
|
|
40
40
|
spec.add_development_dependency 'pry'
|
|
41
41
|
spec.add_development_dependency 'pry-rails', '~> 0.3'
|
|
42
42
|
spec.add_development_dependency 'rake', '~> 12.0'
|
|
43
|
-
spec.add_development_dependency 'rubocop', '~>
|
|
43
|
+
spec.add_development_dependency 'rubocop', '~> 1'
|
|
44
|
+
spec.add_development_dependency 'standard', '~> 1'
|
|
44
45
|
spec.add_development_dependency 'sqlite3', '~> 1.4'
|
|
46
|
+
spec.add_development_dependency 'sidekiq', '~> 7'
|
|
45
47
|
end
|
metadata
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: servitium
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tom de Grunt
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2024-04-10 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: active_attr
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - "
|
|
17
|
+
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: '0.15'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- - "
|
|
24
|
+
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '0.15'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
@@ -198,14 +198,28 @@ dependencies:
|
|
|
198
198
|
requirements:
|
|
199
199
|
- - "~>"
|
|
200
200
|
- !ruby/object:Gem::Version
|
|
201
|
-
version: '
|
|
201
|
+
version: '1'
|
|
202
|
+
type: :development
|
|
203
|
+
prerelease: false
|
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
205
|
+
requirements:
|
|
206
|
+
- - "~>"
|
|
207
|
+
- !ruby/object:Gem::Version
|
|
208
|
+
version: '1'
|
|
209
|
+
- !ruby/object:Gem::Dependency
|
|
210
|
+
name: standard
|
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
|
212
|
+
requirements:
|
|
213
|
+
- - "~>"
|
|
214
|
+
- !ruby/object:Gem::Version
|
|
215
|
+
version: '1'
|
|
202
216
|
type: :development
|
|
203
217
|
prerelease: false
|
|
204
218
|
version_requirements: !ruby/object:Gem::Requirement
|
|
205
219
|
requirements:
|
|
206
220
|
- - "~>"
|
|
207
221
|
- !ruby/object:Gem::Version
|
|
208
|
-
version: '
|
|
222
|
+
version: '1'
|
|
209
223
|
- !ruby/object:Gem::Dependency
|
|
210
224
|
name: sqlite3
|
|
211
225
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -220,6 +234,20 @@ dependencies:
|
|
|
220
234
|
- - "~>"
|
|
221
235
|
- !ruby/object:Gem::Version
|
|
222
236
|
version: '1.4'
|
|
237
|
+
- !ruby/object:Gem::Dependency
|
|
238
|
+
name: sidekiq
|
|
239
|
+
requirement: !ruby/object:Gem::Requirement
|
|
240
|
+
requirements:
|
|
241
|
+
- - "~>"
|
|
242
|
+
- !ruby/object:Gem::Version
|
|
243
|
+
version: '7'
|
|
244
|
+
type: :development
|
|
245
|
+
prerelease: false
|
|
246
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
247
|
+
requirements:
|
|
248
|
+
- - "~>"
|
|
249
|
+
- !ruby/object:Gem::Version
|
|
250
|
+
version: '7'
|
|
223
251
|
description: An implementation of the command pattern for Ruby
|
|
224
252
|
email:
|
|
225
253
|
- tom@degrunt.nl
|
|
@@ -227,7 +255,9 @@ executables: []
|
|
|
227
255
|
extensions: []
|
|
228
256
|
extra_rdoc_files: []
|
|
229
257
|
files:
|
|
258
|
+
- ".github/workflows/gem-push.yml"
|
|
230
259
|
- ".gitignore"
|
|
260
|
+
- ".rubocop.yml"
|
|
231
261
|
- ".travis.yml"
|
|
232
262
|
- CODE_OF_CONDUCT.md
|
|
233
263
|
- Gemfile
|
|
@@ -243,6 +273,7 @@ files:
|
|
|
243
273
|
- lib/generators/servitium/templates/service_test.rb
|
|
244
274
|
- lib/servitium.rb
|
|
245
275
|
- lib/servitium/capture_exceptions_mixin.rb
|
|
276
|
+
- lib/servitium/configuration.rb
|
|
246
277
|
- lib/servitium/context.rb
|
|
247
278
|
- lib/servitium/context_failure.rb
|
|
248
279
|
- lib/servitium/context_model.rb
|
|
@@ -252,7 +283,8 @@ files:
|
|
|
252
283
|
- lib/servitium/rails/railtie.rb
|
|
253
284
|
- lib/servitium/scoped_attributes.rb
|
|
254
285
|
- lib/servitium/service.rb
|
|
255
|
-
- lib/servitium/
|
|
286
|
+
- lib/servitium/service_active_job.rb
|
|
287
|
+
- lib/servitium/service_sidekiq_job.rb
|
|
256
288
|
- lib/servitium/sub_contexts.rb
|
|
257
289
|
- lib/servitium/transactional_mixin.rb
|
|
258
290
|
- lib/servitium/version.rb
|
|
@@ -264,7 +296,7 @@ licenses:
|
|
|
264
296
|
metadata:
|
|
265
297
|
homepage_uri: https://entropydecelerator.com/components/servitium
|
|
266
298
|
source_code_uri: https://code.entropydecelerator.com/components/servitium
|
|
267
|
-
post_install_message:
|
|
299
|
+
post_install_message:
|
|
268
300
|
rdoc_options: []
|
|
269
301
|
require_paths:
|
|
270
302
|
- lib
|
|
@@ -279,8 +311,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
279
311
|
- !ruby/object:Gem::Version
|
|
280
312
|
version: '0'
|
|
281
313
|
requirements: []
|
|
282
|
-
rubygems_version: 3.
|
|
283
|
-
signing_key:
|
|
314
|
+
rubygems_version: 3.4.10
|
|
315
|
+
signing_key:
|
|
284
316
|
specification_version: 4
|
|
285
317
|
summary: Service objects
|
|
286
318
|
test_files: []
|