-
-
Notifications
You must be signed in to change notification settings - Fork 179
fix(etl): skip errored state and interrupt flush wait on table-copy shutdown #881
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -400,6 +400,21 @@ where | |
| ) -> EtlResult<Option<TableSyncWorkerResult>> { | ||
| error!(table_id = table_id.0, error = %err, "table sync worker failed"); | ||
|
|
||
| // A failure that surfaces while shutdown is already in progress is a | ||
| // consequence of the shutdown itself (e.g. the destination rejects or | ||
| // drops in-flight work), not a replication problem. Do not persist it: | ||
| // a stored `Errored` state is never retried across restarts, so the | ||
| // table would otherwise stall on every later run. A dropped sender also | ||
| // counts as shutdown. | ||
| if shutdown_rx.has_changed().unwrap_or(true) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not the correct solution for a concurrent system like ETL. Having the shutdown being
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's fair. We'd just like to be able to drop the acknowledgements once we've initiated the shutdown.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you give me more context on your ETL use case? So that I can see how we can better design shutdown in case.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason of why I am saying this is that, the shutdown on the destination is called on purpose after all of ETL is done, so that we can stop producing data on our end and then the destination can perform teardown. The failure should not happen because a destination is technically unaware of shutdown until ETL won't be interested anymore about the result. And if the result is sent back and the channel is closed a warning will be raised. if tx.send(result).is_err() {
warn!("could not send async result because receiver was already closed");
}
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Our use case is the Postgres CDC input connector for feldera. We want the connector to snapshot, and then follow the cdc stream, this works. But we'd also like to ensure fault tolerance and be able to reingest the table in cases of failure. In cases of failure, the connector sees that the pipeline is shutting down, and triggers the etl pipeline to shutdown as well. And in such cases, returns from Because we've already requested a shutdown here, we want this to be okay. Related: The Accept / Durable api for table copy, currently on Accept can currently allow the table to transition to Ready, causing etl to skip reingesting on restart. I do not think that Accept should have this durable side effect.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yeah, I get what you mean. The thing here is that we need to clarify the semantics. I feel like from ETL's side, if a channel is closed without a response, it's a problem. The destination should take care of sending back a response. Maybe we could classify a response as "gracefully stop". But from my idea, I would like the system to be like, if there is shutdown after the write_table_rows method, we immediately return. Would that work?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I don't think I quite understand the immediately return model. Do you mean something like a biased tokio select, on shutdown.changed() and the But yes, the gracefully stop idea, for shutdown during
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One question I would have is. I assume your The reason I am asking is that ETL is designed in a way where the shutdown procedure of a destination should be made in the
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes. As the connector is part of the pipeline, the shutdown procedure cannot quite be contained in the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would make the implementation quite a bit uglier, is this a problem also for the apply loop? |
||
| info!( | ||
| table_id = table_id.0, | ||
| "table sync worker failed during shutdown, skipping error state persistence" | ||
| ); | ||
|
|
||
| return Ok(Some(TableSyncWorkerResult::Shutdown)); | ||
| } | ||
|
|
||
| // Build a retry policy from the shared classifier. The concrete retry timestamp | ||
| // is computed in the worker from config so both table sync and apply | ||
| // worker use the same retry timing settings. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fair but I think it would be better if we make an abstraction which behind the scenes waits for shutdown on a result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am working now on a PR to do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#900 this is the PR in progress btw
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the fix!