forked from matter-labs/zksync-era
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(node_framework): Support for preconditions and oneshot tasks (ma…
…tter-labs#1398) This PR consists of three parts in one (sorry for that). ## Part 1. Preconditions An alternative take on matter-labs#1290 In short: - Adds two new concepts to the framework: `Precondition` and `UnconstrainedTask`. - Any precondition is a future that must successfully resolve before tasks can be started. An example of future precondition may be the readiness of storage after snapshot sync. - Any `Task` will wait until all of the added preconditions successfully resolves. - An `UnconstrainedTask` is a way to opt-out from waiting for preconditions to complete. These may be useful in two cases: * If you have a stateless component that should start ASAP (e.g. healthcheck server). * If your task is supposed to ensure that precondition is met (e.g. task that does state recovery). The last point is important, btw: imagine that the node runs as a set of microservices on different machines. The precondition should be present on *all* machines (e.g. simply wait until it's ensured), but the corresponding unconstrained task should be run on *just one* machine (since it alters state). In the current impl there is no way to subscribe to a certain set of preconditions or opt-out from a single precondition. You either have to wait for them all or may rely on none. This is done on purpose to not overcomplicate the publicly facing interface. The expectation is that `Task` is a working default that people may just pick up and it'll be guaranteed to work. You only need to meet extra complexity when a `Task` is not enough for you. ## Part 2. Oneshot tasks Adds a notion of oneshot tasks and adds support of running the service in an oneshot mode (e.g. when we *only* add oneshot tasks and expect the node to exit as soon as *all of them* resolve). It comes in two flavors: - `OneshotTask`. An oneshot analog of `Task`. - `UnconstrainedOneshotTask`. An oneshot analog of `UnconstrainedTask`. May be useful, for example, to enforce some `Precondition` and then exit. This way the logical flow of the node is as follows: 1. Start all the unconstrained tasks, unconstrained oneshot tasks, and preconditions. 2. Wait for all the preconditions to resolve. 3. Start all the tasks and oneshot tasks. 4. Wait for any of long-running tasks (i.e. *not* oneshot) to exit. ## Part 3. Refactoring There was a lot of new logic added, so the `ZkSyncService::run` became pretty messy. The most notable part here is that now all flavors of tasks are managed by the new `Runnables` collection that encapsulates the logic of turning different tasks into futures that can be launched by the service.
- Loading branch information
Showing
11 changed files
with
536 additions
and
114 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -916,4 +916,5 @@ balancer | |
lookups | ||
stateful | ||
WIP | ||
oneshot | ||
p2p |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
use std::sync::Arc; | ||
|
||
use tokio::sync::Barrier; | ||
|
||
use crate::service::StopReceiver; | ||
|
||
#[async_trait::async_trait] | ||
pub trait Precondition: 'static + Send + Sync { | ||
/// Unique name of the precondition. | ||
fn name(&self) -> &'static str; | ||
|
||
async fn check(self: Box<Self>, stop_receiver: StopReceiver) -> anyhow::Result<()>; | ||
} | ||
|
||
impl dyn Precondition { | ||
/// An internal helper method that runs a precondition check and lifts the barrier as soon | ||
/// as the check is finished. | ||
pub(super) async fn check_with_barrier( | ||
self: Box<Self>, | ||
mut stop_receiver: StopReceiver, | ||
preconditions_barrier: Arc<Barrier>, | ||
) -> anyhow::Result<()> { | ||
self.check(stop_receiver.clone()).await?; | ||
tokio::select! { | ||
_ = preconditions_barrier.wait() => { | ||
Ok(()) | ||
} | ||
_ = stop_receiver.0.changed() => { | ||
Ok(()) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.