-
Notifications
You must be signed in to change notification settings - Fork 119
feat: Readiness endpoint #2188
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: next
Are you sure you want to change the base?
feat: Readiness endpoint #2188
Changes from all commits
bd981ca
e75635e
9a32837
f3d732a
a0cd25e
85ae60b
321758d
be0ed20
f2adfc2
282b91e
c0ed607
cd7d330
f276d03
29ff69d
e999139
f3d2ecf
1f562e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,17 +10,51 @@ use miden_node_utils::tasks::Tasks; | |
| use miden_protocol::block::{BlockNumber, SignedBlock}; | ||
| use miden_protocol::utils::serde::Deserializable; | ||
| use tokio_stream::StreamExt; | ||
| use tonic_health::ServingStatus; | ||
| use tonic_health::server::HealthReporter; | ||
| use tracing::{info, warn}; | ||
|
|
||
| pub(crate) const RECONNECT_DELAY: Duration = Duration::from_secs(5); | ||
|
|
||
| // RPC READINESS | ||
| // ================================================================================================ | ||
|
|
||
| /// Tracks readiness of the RPC API service for a full-node. | ||
| /// | ||
| /// Holds the gRPC [`HealthReporter`] and the readiness threshold. Created by [`Rpc::serve`] | ||
| /// once the health pair is available and passed directly into [`BlockSync`]. | ||
| #[derive(Clone)] | ||
| pub struct RpcReadiness { | ||
| reporter: HealthReporter, | ||
| threshold: u32, | ||
| } | ||
|
|
||
| impl RpcReadiness { | ||
| const SERVICE_NAME: &'static str = "rpc.Api"; | ||
|
|
||
| pub fn new(reporter: HealthReporter, threshold: u32) -> Self { | ||
| Self { reporter, threshold } | ||
| } | ||
|
|
||
| /// Updates the RPC service health status based on the upstream/local tip gap. | ||
| pub async fn update(&self, upstream_tip: BlockNumber, local_tip: BlockNumber) { | ||
| let status = if upstream_tip.as_u32().saturating_sub(local_tip.as_u32()) <= self.threshold { | ||
| ServingStatus::Serving | ||
| } else { | ||
| ServingStatus::NotServing | ||
| }; | ||
| self.reporter.set_service_status(Self::SERVICE_NAME, status).await; | ||
| } | ||
| } | ||
|
Collaborator
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. @Mirko-von-Leipzig Wondering why the rpc sync code is in block producer crate. Maybe in followup I can look at moving the sync related stuff out? Unsure
Collaborator
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. I wasn't sure where else to put it. I'd like the I think the options are either
I don't feel strongly about this 🤷 If you have ideas, or maybe a better name for this crate could be an option? |
||
|
|
||
| // RPC SYNC | ||
| // ================================================================================================ | ||
|
|
||
| /// Synchronizes local state from an upstream RPC service. | ||
| pub struct RpcSync { | ||
| pub state: Arc<State>, | ||
| pub source_rpc: RpcClient, | ||
| pub readiness: RpcReadiness, | ||
| } | ||
|
|
||
| impl RpcSync { | ||
|
|
@@ -30,6 +64,7 @@ impl RpcSync { | |
| let block_sync = BlockSync { | ||
| state: Arc::clone(&self.state), | ||
| source_rpc: self.source_rpc.clone(), | ||
| readiness: self.readiness, | ||
| }; | ||
| let proof_sync = ProofSync { | ||
| state: self.state, | ||
|
|
@@ -49,6 +84,7 @@ impl RpcSync { | |
| struct BlockSync { | ||
| state: Arc<State>, | ||
| source_rpc: RpcClient, | ||
| readiness: RpcReadiness, | ||
| } | ||
|
|
||
| struct ProofSync { | ||
|
|
@@ -86,9 +122,13 @@ impl BlockSync { | |
|
|
||
| while let Some(result) = stream.next().await { | ||
| let event = result?; | ||
| let upstream_tip = BlockNumber::from(event.committed_chain_tip); | ||
| let block = SignedBlock::read_from_bytes(&event.block) | ||
| .context("failed to deserialize block from upstream")?; | ||
| self.state.apply_block(block).await?; | ||
|
|
||
| let local_tip = self.state.chain_tip(Finality::Committed).await; | ||
| self.readiness.update(upstream_tip, local_tip).await; | ||
| } | ||
|
|
||
| Ok(()) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.