Skip to content

Commit 0b8ae6d

Browse files
committed
test: pin ordering under concurrent transmit drains
A Greptile review of the branch flagged concurrent effect workers on one actor as an ordering hazard: a later effect's drain deliberately includes a processing sibling, so two workers can deliver overlapping envelope sets. The overlap is the documented at-least-once design and the ingest dedups it on transmit:<effectId>; the reorder cannot happen, because a drain delivers older siblings first and only sends a later envelope after the earlier delivery returned successfully. This test forces the exact interleaving: worker A claims the early effect and stalls inside its delivery, worker B claims the later effect and drains both, then A finishes as a deduplicated replay. The mirror applies [1, 2] and both effects complete. Against a neutered drain that delivers only the claimed effect, the same interleaving fails with the reordering the review predicted, so the test observes the guarantee rather than the implementation.
1 parent 0ef596b commit 0b8ae6d

1 file changed

Lines changed: 40 additions & 0 deletions

File tree

test/integration/transmit_staging_test.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,46 @@ def deliver_to_mirror(envelope)
179179
assert_equal({ "count" => 3, "applied" => [ 1, 2 ] }, mirror_state)
180180
end
181181

182+
test "concurrent executors preserve order and dedup overlapping drains" do
183+
first_delivery_started = Queue.new
184+
release_first_delivery = Queue.new
185+
stall_next_delivery = true
186+
stall_mutex = Mutex.new
187+
SolidObjects.register_transmit do |envelope|
188+
should_stall = stall_mutex.synchronize do
189+
stalling = stall_next_delivery
190+
stall_next_delivery = false
191+
stalling
192+
end
193+
if should_stall
194+
first_delivery_started << true
195+
release_first_delivery.pop
196+
end
197+
deliver_to_mirror(envelope)
198+
end
199+
reference = CounterActor.ref("alice")
200+
reference.async.increment(amount: 1)
201+
reference.async.increment(amount: 2)
202+
worker.run_until_idle
203+
executor_a = SolidObjects::EffectExecutor.new
204+
executor_b = SolidObjects::EffectExecutor.new
205+
206+
stalled_claim = Thread.new { executor_a.run_once }
207+
Timeout.timeout(5) { first_delivery_started.pop }
208+
assert executor_b.run_once
209+
release_first_delivery << true
210+
assert stalled_claim.value
211+
212+
worker.run_until_idle
213+
assert_equal({ "count" => 3, "applied" => [ 1, 2 ] }, mirror_state)
214+
assert_equal %w[completed completed], SolidObjects::Effect.order(:id).pluck(:status)
215+
ensure
216+
release_first_delivery << true
217+
stalled_claim&.join(2)
218+
executor_a&.stop
219+
executor_b&.stop
220+
end
221+
182222
test "recovers in order after an offline period" do
183223
online = false
184224
SolidObjects.register_transmit do |envelope|

0 commit comments

Comments
 (0)