decouplio 1.0.0alpha → 1.0.0alpha3
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/.rubocop.yml +4 -0
- data/README.md +26 -2
- data/benchmarks/Gemfile +2 -1
- data/benchmarks/multi_step_benchmark.rb +336 -0
- data/benchmarks/single_step_benchmark.rb +159 -0
- data/decouplio.gemspec +1 -1
- data/docker-compose.yml +13 -2
- data/docs/aide.rb +59 -0
- data/docs/doby.rb +1 -1
- data/docs/doby_aide.md +208 -0
- data/docs/fail.md +143 -0
- data/docs/fail.rb +126 -29
- data/docs/index.md +1 -1
- data/docs/logic_block.md +4 -0
- data/docs/octo.md +59 -2
- data/docs/quick_start.md +1 -1
- data/docs/resq.md +2 -2
- data/docs/step.md +148 -0
- data/docs/step.rb +119 -18
- data/docs/step_as_a_service.md +25 -11
- data/docs/step_as_a_service.rb +2 -2
- data/docs/wrap.md +8 -0
- data/lib/decouplio/action.rb +22 -3
- data/lib/decouplio/composer.rb +91 -20
- data/lib/decouplio/const/doby_aide_options.rb +15 -0
- data/lib/decouplio/const/reserved_methods.rb +13 -9
- data/lib/decouplio/const/results.rb +2 -0
- data/lib/decouplio/const/types.rb +19 -5
- data/lib/decouplio/const/validations/aide.rb +38 -0
- data/lib/decouplio/const/validations/doby.rb +36 -0
- data/lib/decouplio/const/validations/fail.rb +5 -1
- data/lib/decouplio/const/validations/octo.rb +2 -1
- data/lib/decouplio/errors/aide_can_not_be_first_step_error.rb +18 -0
- data/lib/decouplio/errors/aide_controversial_keys_error.rb +26 -0
- data/lib/decouplio/errors/aide_finish_him_error.rb +26 -0
- data/lib/decouplio/errors/doby_controversial_keys_error.rb +26 -0
- data/lib/decouplio/errors/doby_finish_him_error.rb +26 -0
- data/lib/decouplio/errors/{fail_is_first_step_error.rb → fail_can_not_be_first_step_error.rb} +1 -1
- data/lib/decouplio/errors/step_is_not_defined_for_aide_error.rb +26 -0
- data/lib/decouplio/errors/step_is_not_defined_for_doby_error.rb +27 -0
- data/lib/decouplio/logic_dsl.rb +30 -3
- data/lib/decouplio/options_validator.rb +122 -8
- data/lib/decouplio/steps/aide.rb +37 -0
- data/lib/decouplio/steps/doby.rb +14 -9
- data/lib/decouplio/steps/fail.rb +7 -22
- data/lib/decouplio/steps/inner_action_fail.rb +7 -22
- data/lib/decouplio/steps/inner_action_step.rb +7 -18
- data/lib/decouplio/steps/octo.rb +7 -2
- data/lib/decouplio/steps/service_fail.rb +11 -23
- data/lib/decouplio/steps/service_pass.rb +4 -1
- data/lib/decouplio/steps/service_step.rb +11 -19
- data/lib/decouplio/steps/shared/fail_resolver.rb +40 -0
- data/lib/decouplio/steps/shared/step_resolver.rb +43 -0
- data/lib/decouplio/steps/step.rb +7 -18
- data/lib/decouplio/steps/wrap.rb +7 -18
- data/lib/decouplio/validators/condition.rb +10 -0
- data/lib/decouplio/version.rb +1 -1
- metadata +22 -7
- data/benchmarks/benchmarks.rb +0 -527
- data/docs/doby.md +0 -80
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b52142f648d5043e84d6daa6b36026f33d01a6bd9197d5e6f65ac0fb51abac81
|
4
|
+
data.tar.gz: 7825cc21ae535df0c950c7b5eaf34264d37f6fe13f346282bc3a15e88e4e8b8e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 395c7ca0d0618abd369307426edba5ada1d4dc002f55ff8c0906205e08924a07ec60b0905fd2031860a7b32effbe88265139faf397972ea1359448b5c1572ebb
|
7
|
+
data.tar.gz: 0fa93d697696700e24758eb3b774d183b1e24486a5846273c24d6ff7dc3684876b587e0afb90165bdb3f8bde8deeee938fc78d90361b4d0d2c193eeec7870ac0
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -14,16 +14,40 @@ And then execute:
|
|
14
14
|
|
15
15
|
$ bundle
|
16
16
|
|
17
|
-
Or install it yourself
|
17
|
+
Or install it by yourself:
|
18
18
|
|
19
19
|
$ gem install decouplio
|
20
20
|
|
21
|
-
|
21
|
+
## Currently decouplio is in alpha testing, more features will come soon.
|
22
|
+
|
23
|
+
### Compatibility
|
24
|
+
Ruby:
|
25
|
+
- 2.7
|
26
|
+
- 3.0
|
27
|
+
|
28
|
+
### Docs
|
29
|
+
|
30
|
+
- [Quick start](https://github.com/differencialx/decouplio/blob/master/docs/quick_start.md)
|
31
|
+
- [Logic block](https://github.com/differencialx/decouplio/blob/master/docs/logic_block.md)
|
32
|
+
- [Context](https://github.com/differencialx/decouplio/blob/master/docs/context.md)
|
33
|
+
- [Step](https://github.com/differencialx/decouplio/blob/master/docs/step.md)
|
34
|
+
- [Fail](https://github.com/differencialx/decouplio/blob/master/docs/fail.md)
|
35
|
+
- [Pass](https://github.com/differencialx/decouplio/blob/master/docs/pass.md)
|
36
|
+
- [Octo](https://github.com/differencialx/decouplio/blob/master/docs/octo.md)
|
37
|
+
- [Wrap](https://github.com/differencialx/decouplio/blob/master/docs/wrap.md)
|
38
|
+
- [Resq](https://github.com/differencialx/decouplio/blob/master/docs/resq.md)
|
39
|
+
- [Inner action](https://github.com/differencialx/decouplio/blob/master/docs/inner_action.md)
|
40
|
+
- [Doby/Aide](https://github.com/differencialx/decouplio/blob/master/docs/doby_aide.md)
|
41
|
+
- [Step as a service](https://github.com/differencialx/decouplio/blob/master/docs/step_as_a_service.md)
|
42
|
+
- [Error store](https://github.com/differencialx/decouplio/blob/master/docs/error_store.md)
|
43
|
+
- [Benchmarks](https://github.com/differencialx/decouplio/blob/master/docs/benchmarks.md)
|
22
44
|
|
23
45
|
## Contributing
|
24
46
|
|
25
47
|
Bug reports and pull requests are welcome on GitHub at https://github.com/differencialx/decouplio.
|
26
48
|
|
49
|
+
More detailed description for contribution process will be added later.
|
50
|
+
|
27
51
|
## License
|
28
52
|
|
29
53
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/benchmarks/Gemfile
CHANGED
@@ -0,0 +1,336 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_interaction'
|
4
|
+
require 'interactor'
|
5
|
+
require 'mutations'
|
6
|
+
require 'trailblazer'
|
7
|
+
require 'decouplio'
|
8
|
+
require 'benchmark/ips'
|
9
|
+
|
10
|
+
class RegularServiceTest
|
11
|
+
attr_accessor :ctx, :param1
|
12
|
+
|
13
|
+
def self.call(param1:)
|
14
|
+
new(param1: param1).call
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(param1:)
|
18
|
+
@param1 = param1
|
19
|
+
@ctx = {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def call
|
23
|
+
step_one
|
24
|
+
step_two
|
25
|
+
step_three
|
26
|
+
step_four
|
27
|
+
step_five
|
28
|
+
step_six
|
29
|
+
step_seven
|
30
|
+
step_eight
|
31
|
+
step_nine
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def step_one
|
36
|
+
ctx[:step_one] = param1
|
37
|
+
end
|
38
|
+
|
39
|
+
def step_two
|
40
|
+
ctx[:step_two] = ctx[:step_one]
|
41
|
+
end
|
42
|
+
|
43
|
+
def step_three
|
44
|
+
ctx[:step_three] = ctx[:step_two]
|
45
|
+
end
|
46
|
+
|
47
|
+
def step_four
|
48
|
+
ctx[:step_four] = ctx[:step_three]
|
49
|
+
end
|
50
|
+
|
51
|
+
def step_five
|
52
|
+
ctx[:step_five] = ctx[:step_four]
|
53
|
+
end
|
54
|
+
|
55
|
+
def step_six
|
56
|
+
ctx[:step_six] = ctx[:step_five]
|
57
|
+
end
|
58
|
+
|
59
|
+
def step_seven
|
60
|
+
ctx[:step_seven] = ctx[:step_six]
|
61
|
+
end
|
62
|
+
|
63
|
+
def step_eight
|
64
|
+
ctx[:step_eight] = ctx[:step_seven]
|
65
|
+
end
|
66
|
+
|
67
|
+
def step_nine
|
68
|
+
ctx[:step_nine] = ctx[:step_eight]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class DecouplioTestSeveralSteps < Decouplio::Action
|
73
|
+
logic do
|
74
|
+
step :step_one
|
75
|
+
step :step_two
|
76
|
+
step :step_three
|
77
|
+
step :step_four
|
78
|
+
step :step_five
|
79
|
+
step :step_six
|
80
|
+
step :step_seven
|
81
|
+
step :step_eight
|
82
|
+
step :step_nine
|
83
|
+
end
|
84
|
+
|
85
|
+
def step_one(param1:, **)
|
86
|
+
ctx[:step_one] = param1
|
87
|
+
end
|
88
|
+
|
89
|
+
def step_two(step_one:, **)
|
90
|
+
ctx[:step_two] = step_one
|
91
|
+
end
|
92
|
+
|
93
|
+
def step_three(step_two:, **)
|
94
|
+
ctx[:step_three] = step_two
|
95
|
+
end
|
96
|
+
|
97
|
+
def step_four(step_three:, **)
|
98
|
+
ctx[:step_four] = step_three
|
99
|
+
end
|
100
|
+
|
101
|
+
def step_five(step_four:, **)
|
102
|
+
ctx[:step_five] = step_four
|
103
|
+
end
|
104
|
+
|
105
|
+
def step_six(step_five:, **)
|
106
|
+
ctx[:step_six] = step_five
|
107
|
+
end
|
108
|
+
|
109
|
+
def step_seven(step_six:, **)
|
110
|
+
ctx[:step_seven] = step_six
|
111
|
+
end
|
112
|
+
|
113
|
+
def step_eight(step_seven:, **)
|
114
|
+
ctx[:step_eight] = step_seven
|
115
|
+
end
|
116
|
+
|
117
|
+
def step_nine(step_eight:, **)
|
118
|
+
ctx[:step_nine] = step_eight
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
class StepOne
|
123
|
+
include Interactor
|
124
|
+
|
125
|
+
def call
|
126
|
+
context.step_one = context.param1
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
class StepTwo
|
131
|
+
include Interactor
|
132
|
+
|
133
|
+
def call
|
134
|
+
context.step_two = context.step_one
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
class StepThree
|
139
|
+
include Interactor
|
140
|
+
|
141
|
+
def call
|
142
|
+
context.step_three = context.step_two
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
class StepFour
|
147
|
+
include Interactor
|
148
|
+
|
149
|
+
def call
|
150
|
+
context.step_four = context.step_three
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
class StepFive
|
155
|
+
include Interactor
|
156
|
+
|
157
|
+
def call
|
158
|
+
context.step_five = context.step_four
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
class StepSix
|
163
|
+
include Interactor
|
164
|
+
|
165
|
+
def call
|
166
|
+
context.step_six = context.step_five
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
class StepSeven
|
171
|
+
include Interactor
|
172
|
+
|
173
|
+
def call
|
174
|
+
context.step_seven = context.step_six
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
class StepEight
|
179
|
+
include Interactor
|
180
|
+
|
181
|
+
def call
|
182
|
+
context.step_eight = context.step_seven
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
class StepNine
|
187
|
+
include Interactor
|
188
|
+
|
189
|
+
def call
|
190
|
+
context.step_nine = context.step_eight
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
class InteractorTestOrganizer
|
195
|
+
include Interactor::Organizer
|
196
|
+
|
197
|
+
organize StepOne,
|
198
|
+
StepTwo,
|
199
|
+
StepThree,
|
200
|
+
StepFour,
|
201
|
+
StepFive,
|
202
|
+
StepSix,
|
203
|
+
StepSeven,
|
204
|
+
StepEight,
|
205
|
+
StepNine
|
206
|
+
end
|
207
|
+
|
208
|
+
class TrailblazerTestSeveralSteps < Trailblazer::Activity::Railway
|
209
|
+
step :step_one
|
210
|
+
step :step_two
|
211
|
+
step :step_three
|
212
|
+
step :step_four
|
213
|
+
step :step_five
|
214
|
+
step :step_six
|
215
|
+
step :step_seven
|
216
|
+
step :step_eight
|
217
|
+
step :step_nine
|
218
|
+
|
219
|
+
def step_one(ctx, param1:, **)
|
220
|
+
ctx[:step_one] = param1
|
221
|
+
end
|
222
|
+
|
223
|
+
def step_two(ctx, step_one:, **)
|
224
|
+
ctx[:step_two] = step_one
|
225
|
+
end
|
226
|
+
|
227
|
+
def step_three(ctx, step_two:, **)
|
228
|
+
ctx[:step_three] = step_two
|
229
|
+
end
|
230
|
+
|
231
|
+
def step_four(ctx, step_three:, **)
|
232
|
+
ctx[:step_four] = step_three
|
233
|
+
end
|
234
|
+
|
235
|
+
def step_five(ctx, step_four:, **)
|
236
|
+
ctx[:step_five] = step_four
|
237
|
+
end
|
238
|
+
|
239
|
+
def step_six(ctx, step_five:, **)
|
240
|
+
ctx[:step_six] = step_five
|
241
|
+
end
|
242
|
+
|
243
|
+
def step_seven(ctx, step_six:, **)
|
244
|
+
ctx[:step_seven] = step_six
|
245
|
+
end
|
246
|
+
|
247
|
+
def step_eight(ctx, step_seven:, **)
|
248
|
+
ctx[:step_eight] = step_seven
|
249
|
+
end
|
250
|
+
|
251
|
+
def step_nine(ctx, step_eight:, **)
|
252
|
+
ctx[:step_nine] = step_eight
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
class DecouplioStepOne
|
257
|
+
def self.call(ctx:, **)
|
258
|
+
ctx[:step_one] = ctx[:param1]
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
class DecouplioStepTwo
|
263
|
+
def self.call(ctx:, **)
|
264
|
+
ctx[:step_two] = ctx[:step_one]
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
class DecouplioStepThree
|
269
|
+
def self.call(ctx:, **)
|
270
|
+
ctx[:step_three] = ctx[:step_two]
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
class DecouplioStepFour
|
275
|
+
def self.call(ctx:, **)
|
276
|
+
ctx[:step_four] = ctx[:step_three]
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
class DecouplioStepFive
|
281
|
+
def self.call(ctx:, **)
|
282
|
+
ctx[:step_five] = ctx[:step_four]
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
class DecouplioStepSix
|
287
|
+
def self.call(ctx:, **)
|
288
|
+
ctx[:step_six] = ctx[:step_five]
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
class DecouplioStepSeven
|
293
|
+
def self.call(ctx:, **)
|
294
|
+
ctx[:step_seven] = ctx[:step_six]
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
class DecouplioStepEight
|
299
|
+
def self.call(ctx:, **)
|
300
|
+
ctx[:step_eight] = ctx[:step_seven]
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
class DecouplioStepNine
|
305
|
+
def self.call(ctx:, **)
|
306
|
+
ctx[:step_nine] = ctx[:step_eight]
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
class DecouplioServiceStepsTest < Decouplio::Action
|
311
|
+
logic do
|
312
|
+
step DecouplioStepOne
|
313
|
+
step DecouplioStepTwo
|
314
|
+
step DecouplioStepThree
|
315
|
+
step DecouplioStepFour
|
316
|
+
step DecouplioStepFive
|
317
|
+
step DecouplioStepSix
|
318
|
+
step DecouplioStepSeven
|
319
|
+
step DecouplioStepEight
|
320
|
+
step DecouplioStepNine
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
iteration_count = 100_00
|
325
|
+
|
326
|
+
Benchmark.ips do |x|
|
327
|
+
x.report('RegularService') { iteration_count.times { RegularServiceTest.call(param1: 'param1') } }
|
328
|
+
x.report('Decouplio several steps') { iteration_count.times { DecouplioTestSeveralSteps.call(param1: 'param1') } }
|
329
|
+
x.report('Decouplio service steps') { iteration_count.times { DecouplioServiceStepsTest.call(param1: 'param1') } }
|
330
|
+
x.report('Trailblazer several steps') { iteration_count.times { TrailblazerTestSeveralSteps.call(param1: 'param1') } }
|
331
|
+
x.report('Interactor several interactions with organizer') do
|
332
|
+
iteration_count.times { InteractorTestOrganizer.call(param1: 'param1') }
|
333
|
+
end
|
334
|
+
|
335
|
+
x.compare!
|
336
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_interaction'
|
4
|
+
require 'interactor'
|
5
|
+
require 'mutations'
|
6
|
+
require 'trailblazer'
|
7
|
+
require 'decouplio'
|
8
|
+
require 'benchmark/ips'
|
9
|
+
|
10
|
+
class MutationTest < Mutations::Command
|
11
|
+
optional do
|
12
|
+
string :param1
|
13
|
+
end
|
14
|
+
|
15
|
+
def execute
|
16
|
+
@context = {}
|
17
|
+
@context[:step_one] = param1
|
18
|
+
@context[:step_two] = @context[:step_one]
|
19
|
+
@context[:step_three] = @context[:step_two]
|
20
|
+
@context[:step_four] = @context[:step_three]
|
21
|
+
@context[:step_five] = @context[:step_four]
|
22
|
+
@context[:step_six] = @context[:step_five]
|
23
|
+
@context[:step_seven] = @context[:step_six]
|
24
|
+
@context[:step_eight] = @context[:step_seven]
|
25
|
+
@context[:step_nine] = @context[:step_eight]
|
26
|
+
|
27
|
+
@context
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class ActiveInteractionTest < ActiveInteraction::Base
|
32
|
+
string :param1
|
33
|
+
|
34
|
+
def execute
|
35
|
+
@context = {}
|
36
|
+
@context[:step_one] = param1
|
37
|
+
@context[:step_two] = @context[:step_one]
|
38
|
+
@context[:step_three] = @context[:step_two]
|
39
|
+
@context[:step_four] = @context[:step_three]
|
40
|
+
@context[:step_five] = @context[:step_four]
|
41
|
+
@context[:step_six] = @context[:step_five]
|
42
|
+
@context[:step_seven] = @context[:step_six]
|
43
|
+
@context[:step_eight] = @context[:step_seven]
|
44
|
+
@context[:step_nine] = @context[:step_eight]
|
45
|
+
|
46
|
+
@context
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class DecouplioTestOneStep < Decouplio::Action
|
51
|
+
logic do
|
52
|
+
step :step_one
|
53
|
+
end
|
54
|
+
|
55
|
+
def step_one(param1:, **)
|
56
|
+
ctx[:step_one] = param1
|
57
|
+
ctx[:step_two] = ctx[:step_one]
|
58
|
+
ctx[:step_three] = ctx[:step_two]
|
59
|
+
ctx[:step_four] = ctx[:step_three]
|
60
|
+
ctx[:step_five] = ctx[:step_four]
|
61
|
+
ctx[:step_six] = ctx[:step_five]
|
62
|
+
ctx[:step_seven] = ctx[:step_six]
|
63
|
+
ctx[:step_eight] = ctx[:step_seven]
|
64
|
+
ctx[:step_nine] = ctx[:step_eight]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class InteractorWithoutOrganizer
|
69
|
+
include Interactor
|
70
|
+
|
71
|
+
def call
|
72
|
+
context.step_one = context.param1
|
73
|
+
context.step_two = context.step_one
|
74
|
+
context.step_three = context.step_two
|
75
|
+
context.step_four = context.step_three
|
76
|
+
context.step_five = context.step_four
|
77
|
+
context.step_six = context.step_five
|
78
|
+
context.step_seven = context.step_six
|
79
|
+
context.step_eight = context.step_seven
|
80
|
+
context.step_nine = context.step_eight
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class RegularServiceTest
|
85
|
+
attr_accessor :ctx, :param1
|
86
|
+
|
87
|
+
def self.call(param1:)
|
88
|
+
new(param1: param1).call
|
89
|
+
end
|
90
|
+
|
91
|
+
def initialize(param1:)
|
92
|
+
@param1 = param1
|
93
|
+
@ctx = {}
|
94
|
+
end
|
95
|
+
|
96
|
+
def call
|
97
|
+
ctx[:step_one] = param1
|
98
|
+
ctx[:step_two] = ctx[:step_one]
|
99
|
+
ctx[:step_three] = ctx[:step_two]
|
100
|
+
ctx[:step_four] = ctx[:step_three]
|
101
|
+
ctx[:step_five] = ctx[:step_four]
|
102
|
+
ctx[:step_six] = ctx[:step_five]
|
103
|
+
ctx[:step_seven] = ctx[:step_six]
|
104
|
+
ctx[:step_eight] = ctx[:step_seven]
|
105
|
+
ctx[:step_nine] = ctx[:step_eight]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class TrailblazerTestOneStep < Trailblazer::Activity::Railway
|
110
|
+
step :step_one
|
111
|
+
|
112
|
+
def step_one(ctx, param1:, **)
|
113
|
+
ctx[:step_one] = param1
|
114
|
+
ctx[:step_two] = ctx[:step_one]
|
115
|
+
ctx[:step_three] = ctx[:step_two]
|
116
|
+
ctx[:step_four] = ctx[:step_three]
|
117
|
+
ctx[:step_five] = ctx[:step_four]
|
118
|
+
ctx[:step_six] = ctx[:step_five]
|
119
|
+
ctx[:step_seven] = ctx[:step_six]
|
120
|
+
ctx[:step_eight] = ctx[:step_seven]
|
121
|
+
ctx[:step_nine] = ctx[:step_eight]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class ServiceAsStep
|
126
|
+
def self.call(ctx:, **)
|
127
|
+
ctx[:step_one] = ctx[:param1]
|
128
|
+
ctx[:step_two] = ctx[:step_one]
|
129
|
+
ctx[:step_three] = ctx[:step_two]
|
130
|
+
ctx[:step_four] = ctx[:step_three]
|
131
|
+
ctx[:step_five] = ctx[:step_four]
|
132
|
+
ctx[:step_six] = ctx[:step_five]
|
133
|
+
ctx[:step_seven] = ctx[:step_six]
|
134
|
+
ctx[:step_eight] = ctx[:step_seven]
|
135
|
+
ctx[:step_nine] = ctx[:step_eight]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
class DecouplioTestOneStepAsService < Decouplio::Action
|
140
|
+
logic do
|
141
|
+
step ServiceAsStep
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
iteration_count = 100_000
|
146
|
+
|
147
|
+
Benchmark.ips do |x|
|
148
|
+
x.report('Mutation') { iteration_count.times { MutationTest.run(param1: 'param1') } }
|
149
|
+
x.report('ActiveInteraction') { iteration_count.times { ActiveInteractionTest.run(param1: 'param1') } }
|
150
|
+
x.report('Trailblazer one step') { iteration_count.times { TrailblazerTestOneStep.call(param1: 'param1') } }
|
151
|
+
x.report('Interactor one interactor') { iteration_count.times { InteractorWithoutOrganizer.call(param1: 'param1') } }
|
152
|
+
x.report('RegularService') { iteration_count.times { RegularServiceTest.call(param1: 'param1') } }
|
153
|
+
x.report('Decouplio one step') { iteration_count.times { DecouplioTestOneStep.call(param1: 'param1') } }
|
154
|
+
x.report('Decouplio one step as service') do
|
155
|
+
iteration_count.times { DecouplioTestOneStepAsService.call(param1: 'param1') }
|
156
|
+
end
|
157
|
+
|
158
|
+
x.compare!
|
159
|
+
end
|
data/decouplio.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
|
13
13
|
spec.summary = 'Gem for business logic encapsulation'
|
14
14
|
spec.description = "Decouplio is a zero dependency, thread safe and framework agnostic gem designed to encapsulate application business logic. It's reverse engineered through TDD and inspired by such frameworks and gems like Trailblazer, Interactor."
|
15
|
-
spec.homepage = '
|
15
|
+
spec.homepage = 'https://github.com/differencialx/decouplio'
|
16
16
|
spec.license = 'MIT'
|
17
17
|
|
18
18
|
if spec.respond_to?(:metadata)
|
data/docker-compose.yml
CHANGED
@@ -1,11 +1,22 @@
|
|
1
1
|
version: "3.7"
|
2
2
|
|
3
3
|
services:
|
4
|
-
|
4
|
+
benchmark_single_step:
|
5
5
|
build:
|
6
6
|
dockerfile: benchmarks/Dockerfile
|
7
7
|
context: .
|
8
|
-
command: "ruby
|
8
|
+
command: "ruby single_step_benchmark.rb"
|
9
|
+
deploy:
|
10
|
+
resources:
|
11
|
+
limits:
|
12
|
+
cpus: '1'
|
13
|
+
memory: 400M
|
14
|
+
|
15
|
+
benchmark_multi_step:
|
16
|
+
build:
|
17
|
+
dockerfile: benchmarks/Dockerfile
|
18
|
+
context: .
|
19
|
+
command: "ruby multi_step_benchmark.rb"
|
9
20
|
deploy:
|
10
21
|
resources:
|
11
22
|
limits:
|
data/docs/aide.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require_relative '../lib/decouplio'
|
2
|
+
|
3
|
+
class SemanticAide
|
4
|
+
def self.call(ctx:, error_store:, semantic:, error_message:)
|
5
|
+
ctx[:semantic] = semantic
|
6
|
+
error_store.add_error(semantic, error_message)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class SomeAction < Decouplio::Action
|
11
|
+
logic do
|
12
|
+
step :step_one
|
13
|
+
aide SemanticAide, semantic: :bad_request, error_message: 'Bad request'
|
14
|
+
step :step_two
|
15
|
+
end
|
16
|
+
|
17
|
+
def step_one(step_one_param:, **)
|
18
|
+
ctx[:step_one] = step_one_param
|
19
|
+
end
|
20
|
+
|
21
|
+
def step_two(**)
|
22
|
+
ctx[:step_two] = 'Success'
|
23
|
+
end
|
24
|
+
|
25
|
+
def fail_one(**)
|
26
|
+
ctx[:fail_one] = 'Failure'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
success_action = SomeAction.call(step_one_param: true)
|
31
|
+
failure_action = SomeAction.call(step_one_param: false)
|
32
|
+
|
33
|
+
success_action # =>
|
34
|
+
# Result: success
|
35
|
+
|
36
|
+
# Railway Flow:
|
37
|
+
# step_one -> step_two
|
38
|
+
|
39
|
+
# Context:
|
40
|
+
# :step_one_param => true
|
41
|
+
# :step_one => true
|
42
|
+
# :step_two => "Success"
|
43
|
+
|
44
|
+
# Errors:
|
45
|
+
# None
|
46
|
+
|
47
|
+
failure_action # =>
|
48
|
+
# Result: failure
|
49
|
+
|
50
|
+
# Railway Flow:
|
51
|
+
# step_one -> SemanticAide
|
52
|
+
|
53
|
+
# Context:
|
54
|
+
# :step_one_param => false
|
55
|
+
# :step_one => false
|
56
|
+
# :semantic => :bad_request
|
57
|
+
|
58
|
+
# Errors:
|
59
|
+
# :bad_request => ["Bad request"]
|
data/docs/doby.rb
CHANGED