Skip to content

aws/dynamodb: do not wait on close for CDC acks that cannot come - #4989

Open
Leward wants to merge 6 commits into
claude/dynamodb-it-parallelfrom
dynamodb-cdc-close-soft-stop
Open

Leward wants to merge 6 commits into
claude/dynamodb-it-parallelfrom
dynamodb-cdc-close-soft-stop

Conversation

@Leward

@Leward Leward commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #4988.

Summary

Stopping a pipeline with an aws_dynamodb_cdc input in streaming mode took about 10 seconds too long.

On close, the input waited for an ack of every batch it had read. Some of these acks never come:

  • batches still in the input's buffer, which the pipeline never got;
  • batches that Benthos drops at shutdown before they enter the pipeline.

Close now waits only for the acks that are running.
Records that were not acked are not checkpointed, so a restart from a checkpoint reads them again, as before.

This also affects production: the wait used half of the default 20s shutdown_timeout, before the final checkpoints are saved.

Close also no longer sets msgChan and shutSig to nil. This fixes a data race with the Benthos auto-retry wrapper, which can call ReadBatch while Close runs.

Evidence

New TestIntegrationDynamoDBShutdownWithBufferedBatches: a real stream with a slow output stops after the first message, then restarts.

  • Before: the stop takes 10.1s (the test requires less than 5s).
    After: pass. The restart reads all 100 items.

Package integration wall time, on top of #4988: 69.5s before, 10.0s after.

Merge Danger

Door: two-way

Blast Radius: shutdown

Acks after close were already dropped without a checkpoint, so the removed wait never saved a position.

Ref: CON-565

@Leward
Leward added this pull request to stack #4990 October 19, 2026 19:31
Comment thread internal/impl/aws/dynamodb/input_cdc.go Outdated
@Leward Leward changed the title aws/dynamodb: settle undelivered CDC batches on close aws/dynamodb: do not wait on close for CDC acks that cannot come Oct 19, 2026
Comment thread internal/impl/aws/dynamodb/input_cdc_integration_test.go
Close waited for the acks of all batches that the shard readers sent to
the message channel. Batches that stay in the channel are never delivered,
so their acks never come, and Close waited the full shutdown timeout (10s).
Benthos resolves the acks of delivered batches before it calls Close, thus
only the undelivered batches caused the wait.

Close now removes the batches that stay in the channel and calls their ack
functions after it marks the input as closed. These calls release the
tracking and the pending ack. They do not write a checkpoint.

The integration tests now ack the batches that they read, as a pipeline
does. The ack-gate test still does not ack, because it simulates a crash.
The function name and its godoc give the reason for the drain and its
precondition (d.closed is set). Close does not need a labeled loop.
The drain in Close did not fix the real shutdown. Benthos drops a batch
that it read at shutdown without its ack when the batch did not get into
the pipeline. Close waited the full shutdown timeout (10s) for that ack.

Close now waits only for the ack functions that are running. Each ack
function holds a read lock while it checks closed and does its work, and
Close sets closed under the write lock. The pending acks wait group and
the drain are removed. Acks after close were already dropped without a
checkpoint, so the wait did not save a position.

A new integration test stops a real stream with a slow output while the
input has batches in its buffer. The stop took 10.1s before this change
and takes about 2s now. A restart reads all records that the first run
did not ack.
Only a restart that resumes from a checkpoint reads them again. Without a
saved checkpoint, start_from: latest skips them.
The Benthos auto-retry wrapper calls ReadBatch from its own goroutine, so
ReadBatch can run while Close runs. ReadBatch reads msgChan and shutSig
without a lock, and Close set them to nil. The new shutdown integration
test found this data race under -race.

Close now keeps both fields. After Close, the soft stop signal makes
ReadBatch return ErrNotConnected.
Use testcontainers.CleanupContainer, report stream.Run errors with t.Error,
and log the Given, When, and Then steps.
@Leward
Leward force-pushed the dynamodb-cdc-close-soft-stop branch from 5100b1c to 7a0c432 Compare October 20, 2026 18:45

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant