shikibu 0.1.0 → 0.2.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/lib/shikibu/storage/sequel_storage.rb +54 -5
- data/lib/shikibu/version.rb +1 -1
- data/lib/shikibu/workflow.rb +32 -24
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5b3b677128439973fcda2120c7377d1de6cc358bd4cd0b3fd9857e089d85de62
|
|
4
|
+
data.tar.gz: 6826b04fff743009f655282d55451c9850066116343c2da1211e7178d451ed6b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3d7c8eb5b7c2722cbb6569659c61fc02540ba5ef9d9d9da55281e9b482e0ff0a567b4434f309010d3faa35aed0ebd6592a97b77826410db3476a34dd80ea4d8b
|
|
7
|
+
data.tar.gz: 842f548cc2394a5a4a0aeb1641812c6e26f9e24d3f9f73bfeba6d262e3598429e102b560069897a75a6ea0ea9319c4fa27b67689c00714e5d6be3a5ccf6156e2
|
|
@@ -33,8 +33,43 @@ module Shikibu
|
|
|
33
33
|
# Transaction Management
|
|
34
34
|
# ============================================
|
|
35
35
|
|
|
36
|
+
# Thread-local storage for transaction state
|
|
37
|
+
# Tracks nesting depth and post-commit callbacks
|
|
38
|
+
def transaction_state
|
|
39
|
+
Thread.current[:shikibu_tx_state] ||= { depth: 0, callbacks: [] }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Register a callback to be executed after successful commit of the outermost transaction
|
|
43
|
+
# @param block [Proc] The callback to execute after commit
|
|
44
|
+
# @raise [RuntimeError] If called outside of a transaction
|
|
45
|
+
def register_post_commit_callback(&block)
|
|
46
|
+
raise 'Not in transaction' unless in_transaction?
|
|
47
|
+
|
|
48
|
+
transaction_state[:callbacks] << block
|
|
49
|
+
end
|
|
50
|
+
|
|
36
51
|
def transaction(&)
|
|
37
|
-
|
|
52
|
+
state = transaction_state
|
|
53
|
+
state[:depth] += 1
|
|
54
|
+
committed = false
|
|
55
|
+
|
|
56
|
+
begin
|
|
57
|
+
result = @db.transaction(&)
|
|
58
|
+
committed = true
|
|
59
|
+
|
|
60
|
+
# Execute callbacks only after successful commit of outermost transaction
|
|
61
|
+
if state[:depth] == 1
|
|
62
|
+
callbacks = state[:callbacks].dup
|
|
63
|
+
state[:callbacks].clear
|
|
64
|
+
callbacks.each(&:call)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
result
|
|
68
|
+
ensure
|
|
69
|
+
state[:depth] -= 1
|
|
70
|
+
# Clear callbacks on rollback (when not committed) at outermost level
|
|
71
|
+
state[:callbacks].clear if state[:depth].zero? && !committed
|
|
72
|
+
end
|
|
38
73
|
end
|
|
39
74
|
|
|
40
75
|
def in_transaction?
|
|
@@ -405,8 +440,15 @@ module Shikibu
|
|
|
405
440
|
)
|
|
406
441
|
end
|
|
407
442
|
|
|
408
|
-
# Send NOTIFY for new message
|
|
409
|
-
|
|
443
|
+
# Send NOTIFY for new message (deferred if in transaction)
|
|
444
|
+
notify_payload = { ch: channel, msg_id: message_id }
|
|
445
|
+
if in_transaction?
|
|
446
|
+
register_post_commit_callback do
|
|
447
|
+
send_notify(Notify::Channel::CHANNEL_MESSAGE, notify_payload)
|
|
448
|
+
end
|
|
449
|
+
else
|
|
450
|
+
send_notify(Notify::Channel::CHANNEL_MESSAGE, notify_payload)
|
|
451
|
+
end
|
|
410
452
|
|
|
411
453
|
message_id
|
|
412
454
|
end
|
|
@@ -588,8 +630,15 @@ module Shikibu
|
|
|
588
630
|
)
|
|
589
631
|
end
|
|
590
632
|
|
|
591
|
-
# Send NOTIFY for new outbox event
|
|
592
|
-
|
|
633
|
+
# Send NOTIFY for new outbox event (deferred if in transaction)
|
|
634
|
+
notify_payload = { evt_id: event_id, evt_type: event_type }
|
|
635
|
+
if in_transaction?
|
|
636
|
+
register_post_commit_callback do
|
|
637
|
+
send_notify(Notify::Channel::OUTBOX_PENDING, notify_payload)
|
|
638
|
+
end
|
|
639
|
+
else
|
|
640
|
+
send_notify(Notify::Channel::OUTBOX_PENDING, notify_payload)
|
|
641
|
+
end
|
|
593
642
|
end
|
|
594
643
|
|
|
595
644
|
def get_pending_outbox_events(limit: 100)
|
data/lib/shikibu/version.rb
CHANGED
data/lib/shikibu/workflow.rb
CHANGED
|
@@ -279,21 +279,24 @@ module Shikibu
|
|
|
279
279
|
end
|
|
280
280
|
|
|
281
281
|
def execute_single_compensation(comp, compensation_id)
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
282
|
+
# Execute compensation and record result atomically in a transaction
|
|
283
|
+
ctx.storage.transaction do
|
|
284
|
+
comp[:block].call
|
|
285
|
+
|
|
286
|
+
# Record successful compensation (Romancy/Edda compatible format)
|
|
287
|
+
ctx.storage.append_history(
|
|
288
|
+
instance_id: ctx.instance_id,
|
|
289
|
+
activity_id: "compensation:#{compensation_id || comp[:activity_id]}",
|
|
290
|
+
event_type: EventType::COMPENSATION_EXECUTED,
|
|
291
|
+
event_data: {
|
|
292
|
+
compensation_id: compensation_id,
|
|
293
|
+
activity_id: comp[:activity_id],
|
|
294
|
+
activity_name: comp[:compensation_name]
|
|
295
|
+
}
|
|
296
|
+
)
|
|
297
|
+
end
|
|
295
298
|
rescue StandardError => e
|
|
296
|
-
# Record failed compensation but continue with others
|
|
299
|
+
# Record failed compensation but continue with others (outside transaction)
|
|
297
300
|
ctx.storage.append_history(
|
|
298
301
|
instance_id: ctx.instance_id,
|
|
299
302
|
activity_id: "compensation:#{compensation_id || comp[:activity_id]}",
|
|
@@ -320,23 +323,28 @@ module Shikibu
|
|
|
320
323
|
# Call hooks
|
|
321
324
|
ctx.hooks&.on_activity_start&.call(ctx.instance_id, activity_id, name, attempt)
|
|
322
325
|
|
|
323
|
-
result
|
|
326
|
+
# Execute activity and record result atomically in a transaction
|
|
327
|
+
result = ctx.storage.transaction do
|
|
328
|
+
res = block.call
|
|
329
|
+
|
|
330
|
+
# Record successful result (atomic with activity execution)
|
|
331
|
+
ctx.storage.append_history(
|
|
332
|
+
instance_id: ctx.instance_id,
|
|
333
|
+
activity_id: activity_id,
|
|
334
|
+
event_type: EventType::ACTIVITY_COMPLETED,
|
|
335
|
+
event_data: { result: res }
|
|
336
|
+
)
|
|
324
337
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
instance_id: ctx.instance_id,
|
|
328
|
-
activity_id: activity_id,
|
|
329
|
-
event_type: EventType::ACTIVITY_COMPLETED,
|
|
330
|
-
event_data: { result: result }
|
|
331
|
-
)
|
|
338
|
+
res
|
|
339
|
+
end
|
|
332
340
|
|
|
333
|
-
# Cache for replay
|
|
341
|
+
# Cache for replay (outside transaction)
|
|
334
342
|
ctx.cache_result(activity_id, {
|
|
335
343
|
event_type: EventType::ACTIVITY_COMPLETED,
|
|
336
344
|
result: result
|
|
337
345
|
})
|
|
338
346
|
|
|
339
|
-
# Call hooks
|
|
347
|
+
# Call hooks (outside transaction)
|
|
340
348
|
ctx.hooks&.on_activity_complete&.call(ctx.instance_id, activity_id, name, result, false)
|
|
341
349
|
|
|
342
350
|
return result
|