trailblazer-activity 0.12.2 → 0.13.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/CHANGES.md +8 -0
- data/README.md +7 -7
- data/lib/trailblazer/activity/task_builder.rb +11 -3
- data/lib/trailblazer/activity/task_wrap/pipeline.rb +18 -4
- data/lib/trailblazer/activity/task_wrap/variable_mapping.rb +9 -16
- data/lib/trailblazer/activity/task_wrap.rb +3 -3
- data/lib/trailblazer/activity/version.rb +1 -1
- metadata +7 -8
- data/lib/trailblazer/activity/task_wrap/inject.rb +0 -39
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 36888239a75b308074977ecb9637e421940f63a53fdafbadb5a65106152fc550
|
|
4
|
+
data.tar.gz: 3aff2a8fb3da591b98f72f387555791c8273dc02968b68a5f4eb8d59a69f7e45
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bffee75027f1af8e1dd87487f07505bc5e8238e62eb67ffc1a128f90fbaeb5d4feadcbac2294991ef69febd71245292dd39128fd52e78bba11a9be8afce1cdf9
|
|
7
|
+
data.tar.gz: 8ac7bc2b36e8db2349134ce935d1da0881a749c881dca6703c1ed192862d526a734de5da8c956f59b60293300f3dd3fabb05c0e21fbd5187cf2a53b09992c368
|
data/CHANGES.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
# 0.13.0
|
|
2
|
+
|
|
3
|
+
* Removed `TaskWrap::Inject::Defaults`. This is now implemented through `dsl`'s `:inject` option.
|
|
4
|
+
* Removed `TaskWrap::VariableMapping.Extension`.
|
|
5
|
+
* Renamed private `TaskWrap::VariableMapping.merge_for` to `.merge_instructions_for` as there's no {Merge} instance, yet.
|
|
6
|
+
* Extract invocation logic in `TaskBuilder::Task` into `Task#call_option`.
|
|
7
|
+
* Add `TaskWrap::Pipeline::prepend`.
|
|
8
|
+
|
|
1
9
|
# 0.12.2
|
|
2
10
|
|
|
3
11
|
* Use extracted `trailblazer-option`.
|
data/README.md
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
Implements Intermediate, Implementation and compiler
|
|
4
4
|
|
|
5
|
-
The `activity` gem
|
|
5
|
+
The `activity` gem implements the runtime logic to invoke a new abstraction called "activities". Ideally, activities are defined using the [`dsl-linear` DSL gem](https://github.com/trailblazer/trailblazer-activity-dsl-linear).
|
|
6
6
|
|
|
7
7
|
A process is a set of arbitrary pieces of logic you define, chained together and put into a meaningful context by an activity. Activity lets you focus on the implementation of steps while Trailblazer takes care of the control flow.
|
|
8
8
|
|
|
9
|
-
Please find the [full documentation on the Trailblazer website](https://
|
|
9
|
+
Please find the [full documentation on the Trailblazer website](https://trailblazer.to/2.1/docs/activity.html).
|
|
10
10
|
|
|
11
11
|
## Example
|
|
12
12
|
|
|
13
|
-
In conjunction with [`dsl-linear`](https://github.com/trailblazer/trailblazer-activity-dsl-linear), the `activity` gem provides three default patterns to model processes: `Path`, `Railway` and `FastTrack`. Here's an example of what a railway activity could look like, along with some more complex connections (you can read more about Railway strategy in the [docs](https://
|
|
13
|
+
In conjunction with [`dsl-linear`](https://github.com/trailblazer/trailblazer-activity-dsl-linear), the `activity` gem provides three default patterns to model processes: `Path`, `Railway` and `FastTrack`. Here's an example of what a railway activity could look like, along with some more complex connections (you can read more about Railway strategy in the [docs](https://trailblazer.to/2.1/docs/activity.html#activity-strategy-railway)).
|
|
14
14
|
|
|
15
15
|
```ruby
|
|
16
16
|
require "trailblazer-activity"
|
|
@@ -78,15 +78,15 @@ With Activity, modeling business processes turns out to be ridiculously simple:
|
|
|
78
78
|
|
|
79
79
|
## Operation
|
|
80
80
|
|
|
81
|
-
Trailblazer's [`Operation`](https://
|
|
81
|
+
Trailblazer's [`Operation`](https://trailblazer.to/2.1/docs/operation.html#operation-overview) internally uses an activity to model the processes.
|
|
82
82
|
|
|
83
83
|
## Workflow
|
|
84
|
-
Activities can be formed into bigger compounds and using workflow, you can build long-running processes such as a moderated blog post or a parcel delivery. Also, you don't have to use the DSL but can use the [`editor`](https://
|
|
84
|
+
Activities can be formed into bigger compounds and using workflow, you can build long-running processes such as a moderated blog post or a parcel delivery. Also, you don't have to use the DSL but can use the [`editor`](https://trailblazer.to/2.1/docs/pro.html#pro-editor)instead(cool for more complex, long-running flows). Here comes a sample screenshot.
|
|
85
85
|
|
|
86
|
-
<img src="http://
|
|
86
|
+
<img src="http://trailblazer.to/2.1/dist/img/flow.png">
|
|
87
87
|
|
|
88
88
|
## License
|
|
89
89
|
|
|
90
90
|
© Copyright 2018, Trailblazer GmbH
|
|
91
91
|
|
|
92
|
-
Licensed under the LGPLv3 license. We also offer a commercial-friendly [license](https://
|
|
92
|
+
Licensed under the LGPLv3 license. We also offer a commercial-friendly [license](https://trailblazer.to/2.1/docs/pro.html#pro-license).
|
|
@@ -18,17 +18,20 @@ module Trailblazer
|
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
+
# Wraps a {task} (that usually expects the task interface) into a circuit interface
|
|
22
|
+
# that can be used directly in a {Circuit}.
|
|
23
|
+
# We expect {task} to be exposing an {Option()} interface when calling it.
|
|
21
24
|
class Task
|
|
22
25
|
def initialize(task, user_proc)
|
|
23
26
|
@task = task
|
|
24
27
|
@user_proc = user_proc
|
|
25
|
-
|
|
26
28
|
freeze
|
|
27
29
|
end
|
|
28
30
|
|
|
29
|
-
def call(
|
|
31
|
+
def call((ctx, flow_options), **circuit_options)
|
|
30
32
|
# Execute the user step with TRB's kw args.
|
|
31
|
-
|
|
33
|
+
# {@task} is/implements {Trailblazer::Option} interface.
|
|
34
|
+
result = call_option(@task, [ctx, flow_options], **circuit_options)
|
|
32
35
|
|
|
33
36
|
# Return an appropriate signal which direction to go next.
|
|
34
37
|
signal = Activity::TaskBuilder.binary_signal_for(result, Activity::Right, Activity::Left)
|
|
@@ -36,6 +39,11 @@ module Trailblazer
|
|
|
36
39
|
return signal, [ctx, flow_options]
|
|
37
40
|
end
|
|
38
41
|
|
|
42
|
+
# Invoke the original {user_proc} that is wrapped in an {Option()}.
|
|
43
|
+
private def call_option(task_with_option_interface, (ctx, _flow_options), **circuit_options)
|
|
44
|
+
task_with_option_interface.(ctx, keyword_arguments: ctx.to_hash, **circuit_options) # circuit_options contains :exec_context.
|
|
45
|
+
end
|
|
46
|
+
|
|
39
47
|
def inspect # TODO: make me private!
|
|
40
48
|
%{#<Trailblazer::Activity::TaskBuilder::Task user_proc=#{Trailblazer::Activity::Introspect.render_task(@user_proc)}>}
|
|
41
49
|
end
|
|
@@ -17,7 +17,7 @@ class Trailblazer::Activity
|
|
|
17
17
|
attr_reader :sequence
|
|
18
18
|
|
|
19
19
|
def self.insert_before(pipe, before_id, insertion)
|
|
20
|
-
index =
|
|
20
|
+
index = find_index(pipe, before_id)
|
|
21
21
|
|
|
22
22
|
seq = pipe.sequence.dup
|
|
23
23
|
|
|
@@ -25,18 +25,32 @@ class Trailblazer::Activity
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def self.insert_after(pipe, after_id, insertion)
|
|
28
|
-
index =
|
|
28
|
+
index = find_index(pipe, after_id)
|
|
29
29
|
|
|
30
30
|
seq = pipe.sequence.dup
|
|
31
31
|
|
|
32
32
|
Pipeline.new(seq.insert(index+1, insertion))
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
def self.append(pipe, _, insertion)
|
|
35
|
+
def self.append(pipe, _, insertion)
|
|
36
36
|
Pipeline.new(pipe.sequence + [insertion])
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
def self.prepend(pipe, insertion_id, insertion, replace: 0)
|
|
40
|
+
return Pipeline.new(insertion.to_a + pipe.sequence) if insertion_id.nil?
|
|
41
|
+
|
|
42
|
+
index = find_index(pipe, insertion_id)
|
|
43
|
+
|
|
44
|
+
Pipeline.new(pipe.sequence[0..index-1] + insertion.to_a + pipe.sequence[index+replace..-1])
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @private
|
|
48
|
+
def self.find_index(pipe, id)
|
|
49
|
+
index = pipe.sequence.find_index { |(seq_id, _)| seq_id == id }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# Merges {extension_rows} into the {Pipeline} instance.
|
|
40
54
|
# This is usually used in step extensions or at runtime for {wrap_runtime}.
|
|
41
55
|
#
|
|
42
56
|
# {Extension} API
|
|
@@ -5,17 +5,11 @@ class Trailblazer::Activity
|
|
|
5
5
|
# translate them into a {DSL::Extension}.
|
|
6
6
|
#
|
|
7
7
|
# Note that the two options are not the only way to create filters, you can use the
|
|
8
|
-
# more low-level {Scoped()}
|
|
8
|
+
# more low-level {Scoped()} from the `dsl` gem, too, and write your own filter logic.
|
|
9
9
|
module VariableMapping
|
|
10
|
-
#
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
merge: merge_for(input, output, id: id),
|
|
14
|
-
)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# DISCUSS: do we want the automatic wrapping of {input} and {output}?
|
|
18
|
-
def self.merge_for(input, output, id:) # TODO: rename
|
|
10
|
+
# Places filters before/after the {call_task}.
|
|
11
|
+
# Note that {input} and {output} are automatically wrapped.
|
|
12
|
+
def self.merge_instructions_for(input, output, id:)
|
|
19
13
|
[
|
|
20
14
|
[TaskWrap::Pipeline.method(:insert_before), "task_wrap.call_task", ["task_wrap.input", TaskWrap::Input.new(input, id: id)]],
|
|
21
15
|
[TaskWrap::Pipeline.method(:insert_after), "task_wrap.call_task", ["task_wrap.output", TaskWrap::Output.new(output, id: id)]],
|
|
@@ -37,9 +31,10 @@ class Trailblazer::Activity
|
|
|
37
31
|
@id = id
|
|
38
32
|
end
|
|
39
33
|
|
|
40
|
-
# {input.call()} is invoked in the
|
|
41
|
-
#
|
|
42
|
-
#
|
|
34
|
+
# {input.call()} is invoked in the taskWrap pipeline.
|
|
35
|
+
# {original_args} are the actual args passed to the wrapped task: [ [ctx, ..], circuit_options ]
|
|
36
|
+
# We now swap the ctx in {original_args} and our filtered one. The original "outside" ctx is keyed in
|
|
37
|
+
# {wrap_ctx} with the filter ID.
|
|
43
38
|
def call(wrap_ctx, original_args)
|
|
44
39
|
# let user compute new ctx for the wrapped task.
|
|
45
40
|
input_ctx = apply_filter(*original_args)
|
|
@@ -71,9 +66,7 @@ class Trailblazer::Activity
|
|
|
71
66
|
|
|
72
67
|
# Runs your filter and replaces the ctx in `wrap_ctx[:return_args]` with the filtered one.
|
|
73
68
|
def call(wrap_ctx, original_args)
|
|
74
|
-
(original_ctx,
|
|
75
|
-
|
|
76
|
-
return_args = wrap_ctx[:return_args]
|
|
69
|
+
(original_ctx, _original_flow_options), original_circuit_options = original_args
|
|
77
70
|
|
|
78
71
|
returned_ctx, returned_flow_options = wrap_ctx[:return_args] # this is the Context returned from {call}ing the wrapped user task.
|
|
79
72
|
original_ctx = wrap_ctx[@id] # grab the original ctx from before which was set in the {:input} filter.
|
|
@@ -14,7 +14,8 @@ module Trailblazer
|
|
|
14
14
|
|
|
15
15
|
# Compute runtime arguments necessary to execute a taskWrap per task of the activity.
|
|
16
16
|
# This method is the top-level entry, called only once for the entire activity graph.
|
|
17
|
-
|
|
17
|
+
# [:wrap_static] The taskWrap used for the topmost activity/operation.
|
|
18
|
+
def invoke(activity, args, wrap_runtime: {}, wrap_static: initial_wrap_static, **circuit_options) # FIXME: why do we need this method?
|
|
18
19
|
circuit_options = circuit_options.merge(
|
|
19
20
|
runner: TaskWrap::Runner,
|
|
20
21
|
wrap_runtime: wrap_runtime,
|
|
@@ -24,7 +25,7 @@ module Trailblazer
|
|
|
24
25
|
)
|
|
25
26
|
|
|
26
27
|
# signal, (ctx, flow), circuit_options =
|
|
27
|
-
Runner.(activity, args, **circuit_options)
|
|
28
|
+
TaskWrap::Runner.(activity, args, **circuit_options)
|
|
28
29
|
end
|
|
29
30
|
|
|
30
31
|
# {:extension} API
|
|
@@ -62,4 +63,3 @@ require "trailblazer/activity/task_wrap/pipeline"
|
|
|
62
63
|
require "trailblazer/activity/task_wrap/call_task"
|
|
63
64
|
require "trailblazer/activity/task_wrap/runner"
|
|
64
65
|
require "trailblazer/activity/task_wrap/variable_mapping"
|
|
65
|
-
require "trailblazer/activity/task_wrap/inject"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: trailblazer-activity
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.13.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nick Sutterer
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-12-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: trailblazer-context
|
|
@@ -108,7 +108,7 @@ dependencies:
|
|
|
108
108
|
- - ">="
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
110
|
version: 0.0.7
|
|
111
|
-
description:
|
|
111
|
+
description:
|
|
112
112
|
email:
|
|
113
113
|
- apotonick@gmail.com
|
|
114
114
|
executables: []
|
|
@@ -135,7 +135,6 @@ files:
|
|
|
135
135
|
- lib/trailblazer/activity/task_builder.rb
|
|
136
136
|
- lib/trailblazer/activity/task_wrap.rb
|
|
137
137
|
- lib/trailblazer/activity/task_wrap/call_task.rb
|
|
138
|
-
- lib/trailblazer/activity/task_wrap/inject.rb
|
|
139
138
|
- lib/trailblazer/activity/task_wrap/pipeline.rb
|
|
140
139
|
- lib/trailblazer/activity/task_wrap/runner.rb
|
|
141
140
|
- lib/trailblazer/activity/task_wrap/variable_mapping.rb
|
|
@@ -146,7 +145,7 @@ homepage: http://trailblazer.to
|
|
|
146
145
|
licenses:
|
|
147
146
|
- LGPL-3.0
|
|
148
147
|
metadata: {}
|
|
149
|
-
post_install_message:
|
|
148
|
+
post_install_message:
|
|
150
149
|
rdoc_options: []
|
|
151
150
|
require_paths:
|
|
152
151
|
- lib
|
|
@@ -161,8 +160,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
161
160
|
- !ruby/object:Gem::Version
|
|
162
161
|
version: '0'
|
|
163
162
|
requirements: []
|
|
164
|
-
rubygems_version: 3.
|
|
165
|
-
signing_key:
|
|
163
|
+
rubygems_version: 3.2.3
|
|
164
|
+
signing_key:
|
|
166
165
|
specification_version: 4
|
|
167
166
|
summary: Runtime code for Trailblazer activities.
|
|
168
167
|
test_files: []
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
class Trailblazer::Activity
|
|
2
|
-
module TaskWrap
|
|
3
|
-
# Allows to inject attributes for a task and defaults them if not.
|
|
4
|
-
# Per default, the defaulting is scoped, meaning only the task will see it.
|
|
5
|
-
module Inject
|
|
6
|
-
module Defaults
|
|
7
|
-
module_function
|
|
8
|
-
|
|
9
|
-
def Extension(defaults)
|
|
10
|
-
# Returns new ctx.
|
|
11
|
-
input = ->((original_ctx, flow_options), circuit_options) do
|
|
12
|
-
defaulted_options = defaults_for(defaults, original_ctx)
|
|
13
|
-
|
|
14
|
-
ctx = original_ctx.merge(defaulted_options)
|
|
15
|
-
|
|
16
|
-
Trailblazer::Context(ctx, {}, flow_options[:context_options])
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
output = ->(new_ctx, (original_ctx, _flow_options), _circuit_options) { # FIXME: use Unscope
|
|
20
|
-
_, mutable_data = new_ctx.decompose
|
|
21
|
-
|
|
22
|
-
# we are only interested in the {mutable_data} part since the disposed part
|
|
23
|
-
# represents the injected/defaulted data.
|
|
24
|
-
original_ctx.merge(mutable_data)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
VariableMapping::Extension(input, output, id: input)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# go through all defaultable options and default them if appropriate.
|
|
31
|
-
def defaults_for(defaults, original_ctx)
|
|
32
|
-
Hash[
|
|
33
|
-
defaults.collect { |k, v| [k, original_ctx[k] || v] } # FIXME: doesn't allow {false/nil} currently.
|
|
34
|
-
]
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end # Inject
|
|
38
|
-
end
|
|
39
|
-
end
|