dirty_pipeline 0.8.3 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/dirty_pipeline/base.rb +16 -11
- data/lib/dirty_pipeline/event.rb +26 -2
- data/lib/dirty_pipeline/pg/queue.rb +4 -0
- data/lib/dirty_pipeline/pg/railway.rb +1 -1
- data/lib/dirty_pipeline/pg/storage.rb +1 -1
- data/lib/dirty_pipeline/redis/queue.rb +4 -0
- data/lib/dirty_pipeline/redis/storage.rb +1 -1
- data/lib/dirty_pipeline/transaction.rb +3 -4
- data/lib/dirty_pipeline/transition.rb +22 -1
- data/lib/dirty_pipeline/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 000ac5cab919b0a6781a640b60a54163ce802a3c1c30a84e937a9ea1f8368e01
|
4
|
+
data.tar.gz: e45766b16965674ac64bd3f8c1d494435ca1af9538cc0fb229ac596c845ee28d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 124a17b8c4b59bbccfc90a7ca7d0bc2c8e6abbad1827db2f875643251e5b34dfbef8a66d39272b89ef775d4b9d2e43981411d8b334f8edb9401087beb4e3b4cb
|
7
|
+
data.tar.gz: 1fa1006ed40dddece9300d713b86d1c1fc934a775e9653615af91162a25dce92b63b9e5ebfce29d0dbfe51370f49bbb2bb415803532526d2282a253867db52cc
|
data/lib/dirty_pipeline/base.rb
CHANGED
@@ -42,12 +42,16 @@ module DirtyPipeline
|
|
42
42
|
@status = Status.success(subject)
|
43
43
|
end
|
44
44
|
|
45
|
-
def find_transition(
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
next
|
50
|
-
|
45
|
+
def find_transition!(event)
|
46
|
+
tname = event.transition
|
47
|
+
event.source = storage.status
|
48
|
+
self.class.transitions_map.fetch(tname.to_s).tap do |from:, **kwargs|
|
49
|
+
next unless railway.operation.eql?("call")
|
50
|
+
next if from == Array(event.source)
|
51
|
+
next if from.include?(event.source.to_s)
|
52
|
+
raise InvalidTransition, "from `#{event.source}` by `#{tname}`"
|
53
|
+
end.tap do |to:, **|
|
54
|
+
event.destination = to if railway.operation.eql?("call")
|
51
55
|
end
|
52
56
|
end
|
53
57
|
|
@@ -128,12 +132,14 @@ module DirtyPipeline
|
|
128
132
|
def execute(event, attempt_retry: false)
|
129
133
|
attempt_retry ? event.attempt_retry! : event.start!
|
130
134
|
|
131
|
-
|
132
|
-
Transaction.new(self, event).call do |destination, action, *args|
|
135
|
+
Transaction.new(self, event).call do |action, *args|
|
133
136
|
state_changes = process_action(action, event, *args)
|
137
|
+
|
134
138
|
event.assign_changes(state_changes)
|
139
|
+
event.complete if event.start?
|
140
|
+
|
135
141
|
next if status.failure?
|
136
|
-
Success(event
|
142
|
+
Success(event)
|
137
143
|
end
|
138
144
|
call_next
|
139
145
|
|
@@ -177,8 +183,7 @@ module DirtyPipeline
|
|
177
183
|
@status = Status.failure(cause, tag: type)
|
178
184
|
end
|
179
185
|
|
180
|
-
def Success(event
|
181
|
-
event.complete(destination)
|
186
|
+
def Success(event)
|
182
187
|
@status = Status.success(subject)
|
183
188
|
end
|
184
189
|
end
|
data/lib/dirty_pipeline/event.rb
CHANGED
@@ -23,6 +23,15 @@ module DirtyPipeline
|
|
23
23
|
)
|
24
24
|
end
|
25
25
|
|
26
|
+
def dup
|
27
|
+
self.class.new(
|
28
|
+
data: data.merge(
|
29
|
+
"uuid" => SecureRandom.uuid,
|
30
|
+
"status" => NEW,
|
31
|
+
)
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
26
35
|
attr_reader :id, :tx_id, :error, :data
|
27
36
|
def initialize(options = {}, data: nil, error: nil)
|
28
37
|
unless options.empty?
|
@@ -54,6 +63,22 @@ module DirtyPipeline
|
|
54
63
|
{data: @data, error: @error}
|
55
64
|
end
|
56
65
|
|
66
|
+
def source
|
67
|
+
data["source"]
|
68
|
+
end
|
69
|
+
|
70
|
+
def source=(value)
|
71
|
+
data["source"] = value
|
72
|
+
end
|
73
|
+
|
74
|
+
def destination
|
75
|
+
data["destination"]
|
76
|
+
end
|
77
|
+
|
78
|
+
def destination=(value)
|
79
|
+
data["destination"] = value
|
80
|
+
end
|
81
|
+
|
57
82
|
%w(args transition cache destination changes).each do |method_name|
|
58
83
|
define_method("#{method_name}") { @data[method_name] }
|
59
84
|
end
|
@@ -90,9 +115,8 @@ module DirtyPipeline
|
|
90
115
|
@data["changes"] = changes
|
91
116
|
end
|
92
117
|
|
93
|
-
def complete
|
118
|
+
def complete
|
94
119
|
@data.merge!(
|
95
|
-
"destination" => destination,
|
96
120
|
"updated_at" => Time.now.utc.iso8601,
|
97
121
|
"status" => SUCCESS,
|
98
122
|
)
|
@@ -139,6 +139,8 @@ module DirtyPipeline
|
|
139
139
|
"txid" => event.tx_id,
|
140
140
|
"transit" => event.transition,
|
141
141
|
"args" => event.args,
|
142
|
+
"source" => event.source,
|
143
|
+
"destination" => event.destination
|
142
144
|
)
|
143
145
|
end
|
144
146
|
|
@@ -151,6 +153,8 @@ module DirtyPipeline
|
|
151
153
|
"transaction_uuid" => unpacked_event["txid"],
|
152
154
|
"transition" => unpacked_event["transit"],
|
153
155
|
"args" => unpacked_event["args"],
|
156
|
+
"source" => unpacked_event["source"],
|
157
|
+
"destination" => unpacked_event["destination"]
|
154
158
|
}
|
155
159
|
)
|
156
160
|
end
|
@@ -59,7 +59,7 @@ module DirtyPipeline
|
|
59
59
|
DO UPDATE SET data = EXCLUDED.data, error = EXCLUDED.error;
|
60
60
|
SQL
|
61
61
|
def commit!(event)
|
62
|
-
store["status"] = event.destination if event.
|
62
|
+
store["status"] = event.destination if event.success?
|
63
63
|
store["state"].merge!(event.changes) unless event.changes.to_h.empty?
|
64
64
|
data, error = {}, {}
|
65
65
|
data = event.data.to_h if event.data.respond_to?(:to_h)
|
@@ -52,6 +52,8 @@ module DirtyPipeline
|
|
52
52
|
"txid" => event.tx_id,
|
53
53
|
"transit" => event.transition,
|
54
54
|
"args" => event.args,
|
55
|
+
"source" => event.source,
|
56
|
+
"destination" => event.destination,
|
55
57
|
)
|
56
58
|
end
|
57
59
|
|
@@ -64,6 +66,8 @@ module DirtyPipeline
|
|
64
66
|
"transaction_uuid" => unpacked_event["txid"],
|
65
67
|
"transition" => unpacked_event["transit"],
|
66
68
|
"args" => unpacked_event["args"],
|
69
|
+
"source" => unpacked_event["source"],
|
70
|
+
"destination" => unpacked_event["destination"]
|
67
71
|
}
|
68
72
|
)
|
69
73
|
end
|
@@ -12,16 +12,15 @@ module DirtyPipeline
|
|
12
12
|
pipeline.schedule_cleanup
|
13
13
|
|
14
14
|
# Split attempts config and event dispatching
|
15
|
-
|
16
|
-
pipeline.find_transition(event.
|
17
|
-
.values_at(:to, :action, :attempts)
|
15
|
+
action, max_attempts_count =
|
16
|
+
pipeline.find_transition!(event).values_at(:action, :attempts)
|
18
17
|
|
19
18
|
storage.commit!(event)
|
20
19
|
|
21
20
|
# FIXME: make configurable, now - hardcoded to AR API
|
22
21
|
# subject.transaction(requires_new: true) do
|
23
22
|
subject.transaction do
|
24
|
-
with_abort_handling { yield(
|
23
|
+
with_abort_handling { yield(action, *event.args) }
|
25
24
|
end
|
26
25
|
rescue => exception
|
27
26
|
event.link_exception(exception)
|
@@ -1,4 +1,6 @@
|
|
1
1
|
module DirtyPipeline
|
2
|
+
class Rollback < StandardError; end
|
3
|
+
|
2
4
|
class Transition
|
3
5
|
def Failure(error)
|
4
6
|
railway&.switch_to(:undo)
|
@@ -7,6 +9,10 @@ module DirtyPipeline
|
|
7
9
|
|
8
10
|
def Success(changes = nil)
|
9
11
|
case railway&.active
|
12
|
+
when "finalize_undo"
|
13
|
+
railway&.switch_to(:undo)
|
14
|
+
when "undo"
|
15
|
+
railway&.switch_to(:finalize_undo) if respond_to?(:finalize_undo)
|
10
16
|
when "call"
|
11
17
|
railway&.switch_to(:finalize) if respond_to?(:finalize)
|
12
18
|
when "finalize"
|
@@ -15,6 +21,13 @@ module DirtyPipeline
|
|
15
21
|
throw :success, changes.to_h
|
16
22
|
end
|
17
23
|
|
24
|
+
def self.finalize_undo(*args, **kwargs)
|
25
|
+
event, pipeline, *args = args
|
26
|
+
instance = new(event, pipeline.railway, *args, **kwargs)
|
27
|
+
return unless instance.respond_to?(:finalize_undo)
|
28
|
+
instance.finalize_undo(pipeline.subject)
|
29
|
+
end
|
30
|
+
|
18
31
|
def self.finalize(*args, **kwargs)
|
19
32
|
event, pipeline, *args = args
|
20
33
|
instance = new(event, pipeline.railway, *args, **kwargs)
|
@@ -25,6 +38,7 @@ module DirtyPipeline
|
|
25
38
|
def self.undo(*args, **kwargs)
|
26
39
|
event, pipeline, *args = args
|
27
40
|
instance = new(event, pipeline.railway, *args, **kwargs)
|
41
|
+
pipeline&.railway&.send(:[], :finalize_undo)&.send(:<<, event)
|
28
42
|
return unless instance.respond_to?(:undo)
|
29
43
|
instance.undo(pipeline.subject)
|
30
44
|
end
|
@@ -32,11 +46,18 @@ module DirtyPipeline
|
|
32
46
|
def self.call(*args, **kwargs)
|
33
47
|
event, pipeline, *args = args
|
34
48
|
instance = new(event, pipeline.railway, *args, **kwargs)
|
35
|
-
pipeline&.railway&.send(:[], :undo)&.send(:<<, event)
|
36
49
|
pipeline&.railway&.send(:[], :finalize)&.send(:<<, event)
|
50
|
+
prepare_undo(pipeline, event)
|
37
51
|
instance.call(pipeline.subject)
|
38
52
|
end
|
39
53
|
|
54
|
+
def self.prepare_undo(pipeline, event)
|
55
|
+
anti_event = event.dup
|
56
|
+
anti_event.source, anti_event.destination =
|
57
|
+
event.destination, event.source
|
58
|
+
pipeline&.railway&.send(:[], :undo)&.send(:unshift, anti_event)
|
59
|
+
end
|
60
|
+
|
40
61
|
attr_reader :event, :railway
|
41
62
|
def initialize(event, railway, *, **)
|
42
63
|
@event = event
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dirty_pipeline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergey Dolganov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sidekiq
|