servitium 1.2.20 → 1.3.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: 583d111f0348dae63479a5dbb6d1dea714e17592eb03c9a8a0a07c84874af455
4
- data.tar.gz: 259ab3b3110de03c89a3b50e95aa983433a6267aae0e2ee7ddaf093314dd3f1f
3
+ metadata.gz: fa6706af0892ab90d3f327cac1d97b5e6ed7b0c6e9fa6fa06484058d9733d78a
4
+ data.tar.gz: 0bf72aac0656de3572940cc6a40dbe3952eb406f7895a002994db1ad7987dc84
5
5
  SHA512:
6
- metadata.gz: e240db38b1ba8c97a2fe898d77546d13474781ff8d5d2e1780eb75279bb5e45ed5afe2e4597de5e38526180a812a9eb1c7cfee90a9b923f9c994bf3dbb301f36
7
- data.tar.gz: 700799659b4f0ae4106a8e22c5b9bcbacc93e01f119351fa19f5bbae9bd4af4e018185963e2451f092dd4a5f92d39e6ef2f706927f375b82721d8035a3b314b6
6
+ metadata.gz: 989ad0d166962653b196c3bdee84878b6f7143c8c190a2cddb9f635d65bb5f64e9555978ebc84a54d6f848f930b678f3b6e089cbceef9f60c52c62a408527d0a
7
+ data.tar.gz: aba51072b58ada34593d1d368f18e13d708f72d5f5cc5567cf4b1602d6750f7f52346ac4303aa3d8f7074a35a014875da8dc60f970c76a24ed06d57a70c43bf2
@@ -0,0 +1,11 @@
1
+ name: Rubygem Push
2
+ on:
3
+ push:
4
+ tags:
5
+ - '*'
6
+ jobs:
7
+ build:
8
+ uses: entdec/_workflows/.github/workflows/gem-push.yml@main
9
+ with:
10
+ public: true
11
+ secrets: inherit
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
- See tests for usage examples.
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
@@ -12,7 +12,3 @@ end
12
12
  Rake.add_rakelib 'lib/tasks'
13
13
 
14
14
  task default: :test
15
-
16
- # Adds the Auxilium semver task
17
- spec = Gem::Specification.find_by_name 'auxilium'
18
- load "#{spec.gem_dir}/lib/tasks/semver.rake"
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class <%= name %>Context < ApplicationContext
4
- attribute :some, type: :string, default: 'new'
4
+ attribute :some, type: String, default: 'new'
5
5
 
6
6
  validates :some, presence: true
7
7
 
@@ -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
@@ -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
 
@@ -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
- Servitium::ServiceJob.perform_later(name, inst.context.attributes_hash)
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 ServiceJob < ActiveJob::Base
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Servitium
4
- VERSION = "1.2.20"
4
+ VERSION = "1.3.0"
5
5
  end
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/service_job'
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', '>= 0.15'
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', '~> 0.79'
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.2.20
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: 2022-11-07 00:00:00.000000000 Z
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: '0.79'
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: '0.79'
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/service_job.rb
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.3.7
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: []