replace Option<SubscribeUpdate>
This commit is contained in:
parent
dfed859d0c
commit
c630c9ed56
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::grpc_subscription_autoreconnect::Message::Reconnecting;
|
||||||
use async_stream::stream;
|
use async_stream::stream;
|
||||||
use futures::{Stream, StreamExt};
|
use futures::{Stream, StreamExt};
|
||||||
use log::{debug, info, log, trace, warn, Level};
|
use log::{debug, info, log, trace, warn, Level};
|
||||||
|
@ -50,6 +51,11 @@ impl GrpcSourceConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum Message {
|
||||||
|
GeyserSubscribeUpdate(SubscribeUpdate),
|
||||||
|
Reconnecting,
|
||||||
|
}
|
||||||
|
|
||||||
enum ConnectionState<S: Stream<Item = Result<SubscribeUpdate, Status>>> {
|
enum ConnectionState<S: Stream<Item = Result<SubscribeUpdate, Status>>> {
|
||||||
NotConnected,
|
NotConnected,
|
||||||
Connecting(JoinHandle<GeyserGrpcClientResult<S>>),
|
Connecting(JoinHandle<GeyserGrpcClientResult<S>>),
|
||||||
|
@ -62,8 +68,7 @@ enum ConnectionState<S: Stream<Item = Result<SubscribeUpdate, Status>>> {
|
||||||
pub fn create_geyser_reconnecting_stream(
|
pub fn create_geyser_reconnecting_stream(
|
||||||
grpc_source: GrpcSourceConfig,
|
grpc_source: GrpcSourceConfig,
|
||||||
commitment_config: CommitmentConfig,
|
commitment_config: CommitmentConfig,
|
||||||
// TODO do we want Option<SubscribeUpdate>
|
) -> impl Stream<Item = Message> {
|
||||||
) -> impl Stream<Item = Option<SubscribeUpdate>> {
|
|
||||||
let label = grpc_source.label.clone();
|
let label = grpc_source.label.clone();
|
||||||
|
|
||||||
// solana_sdk -> yellowstone
|
// solana_sdk -> yellowstone
|
||||||
|
@ -148,18 +153,18 @@ pub fn create_geyser_reconnecting_stream(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
(ConnectionState::Connecting(connection_task), None)
|
(ConnectionState::Connecting(connection_task), Message::Reconnecting)
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionState::Connecting(connection_task) => {
|
ConnectionState::Connecting(connection_task) => {
|
||||||
let subscribe_result = connection_task.await;
|
let subscribe_result = connection_task.await;
|
||||||
|
|
||||||
match subscribe_result {
|
match subscribe_result {
|
||||||
Ok(Ok(subscribed_stream)) => (ConnectionState::Ready(subscribed_stream), None),
|
Ok(Ok(subscribed_stream)) => (ConnectionState::Ready(subscribed_stream), Message::Reconnecting),
|
||||||
Ok(Err(geyser_error)) => {
|
Ok(Err(geyser_error)) => {
|
||||||
// TODO identify non-recoverable errors and cancel stream
|
// TODO identify non-recoverable errors and cancel stream
|
||||||
warn!("Subscribe failed on {} - retrying: {:?}", label, geyser_error);
|
warn!("Subscribe failed on {} - retrying: {:?}", label, geyser_error);
|
||||||
(ConnectionState::WaitReconnect, None)
|
(ConnectionState::WaitReconnect, Message::Reconnecting)
|
||||||
},
|
},
|
||||||
Err(geyser_grpc_task_error) => {
|
Err(geyser_grpc_task_error) => {
|
||||||
panic!("Task aborted - should not happen :{geyser_grpc_task_error}");
|
panic!("Task aborted - should not happen :{geyser_grpc_task_error}");
|
||||||
|
@ -173,17 +178,17 @@ pub fn create_geyser_reconnecting_stream(
|
||||||
match geyser_stream.next().await {
|
match geyser_stream.next().await {
|
||||||
Some(Ok(update_message)) => {
|
Some(Ok(update_message)) => {
|
||||||
trace!("> recv update message from {}", label);
|
trace!("> recv update message from {}", label);
|
||||||
(ConnectionState::Ready(geyser_stream), Some(update_message))
|
(ConnectionState::Ready(geyser_stream), Message::GeyserSubscribeUpdate(update_message))
|
||||||
}
|
}
|
||||||
Some(Err(tonic_status)) => {
|
Some(Err(tonic_status)) => {
|
||||||
// TODO identify non-recoverable errors and cancel stream
|
// TODO identify non-recoverable errors and cancel stream
|
||||||
debug!("! error on {} - retrying: {:?}", label, tonic_status);
|
debug!("! error on {} - retrying: {:?}", label, tonic_status);
|
||||||
(ConnectionState::WaitReconnect, None)
|
(ConnectionState::WaitReconnect, Message::Reconnecting)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
//TODO should not arrive. Mean the stream close.
|
//TODO should not arrive. Mean the stream close.
|
||||||
warn!("! geyser stream closed on {} - retrying", label);
|
warn!("! geyser stream closed on {} - retrying", label);
|
||||||
(ConnectionState::WaitReconnect, None)
|
(ConnectionState::WaitReconnect, Message::Reconnecting)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +197,7 @@ pub fn create_geyser_reconnecting_stream(
|
||||||
ConnectionState::WaitReconnect => {
|
ConnectionState::WaitReconnect => {
|
||||||
info!("Waiting a bit, then connect to {}", label);
|
info!("Waiting a bit, then connect to {}", label);
|
||||||
sleep(Duration::from_secs(1)).await;
|
sleep(Duration::from_secs(1)).await;
|
||||||
(ConnectionState::NotConnected, None)
|
(ConnectionState::NotConnected, Message::Reconnecting)
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // -- match
|
}; // -- match
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
use crate::grpc_subscription_autoreconnect::Message;
|
||||||
|
use crate::grpc_subscription_autoreconnect::Message::GeyserSubscribeUpdate;
|
||||||
use async_stream::stream;
|
use async_stream::stream;
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use log::{debug, info};
|
use log::{debug, info, warn};
|
||||||
use merge_streams::MergeStreams;
|
use merge_streams::MergeStreams;
|
||||||
use solana_sdk::clock::Slot;
|
use solana_sdk::clock::Slot;
|
||||||
use solana_sdk::commitment_config::CommitmentConfig;
|
use solana_sdk::commitment_config::CommitmentConfig;
|
||||||
|
@ -15,7 +17,7 @@ pub trait FromYellowstoneMapper {
|
||||||
/// use streams created by ``create_geyser_reconnecting_stream``
|
/// use streams created by ``create_geyser_reconnecting_stream``
|
||||||
/// note: this is agnostic to the type of the stream
|
/// note: this is agnostic to the type of the stream
|
||||||
pub fn create_multiplex<M>(
|
pub fn create_multiplex<M>(
|
||||||
grpc_source_streams: Vec<impl Stream<Item = Option<SubscribeUpdate>>>,
|
grpc_source_streams: Vec<impl Stream<Item = Message>>,
|
||||||
commitment_config: CommitmentConfig,
|
commitment_config: CommitmentConfig,
|
||||||
mapper: M,
|
mapper: M,
|
||||||
) -> impl Stream<Item = M::Target>
|
) -> impl Stream<Item = M::Target>
|
||||||
|
@ -53,14 +55,14 @@ where
|
||||||
|
|
||||||
fn map_updates<S, E>(merged_streams: S, mapper: E) -> impl Stream<Item = E::Target>
|
fn map_updates<S, E>(merged_streams: S, mapper: E) -> impl Stream<Item = E::Target>
|
||||||
where
|
where
|
||||||
S: Stream<Item = Option<SubscribeUpdate>>,
|
S: Stream<Item = Message>,
|
||||||
E: FromYellowstoneMapper,
|
E: FromYellowstoneMapper,
|
||||||
{
|
{
|
||||||
let mut tip: Slot = 0;
|
let mut tip: Slot = 0;
|
||||||
stream! {
|
stream! {
|
||||||
for await update in merged_streams {
|
for await update in merged_streams {
|
||||||
match update {
|
match update {
|
||||||
Some(update) => {
|
GeyserSubscribeUpdate(update) => {
|
||||||
// take only the update messages we want
|
// take only the update messages we want
|
||||||
if let Some((proposed_slot, block)) = mapper.map_yellowstone_update(update) {
|
if let Some((proposed_slot, block)) = mapper.map_yellowstone_update(update) {
|
||||||
if proposed_slot > tip {
|
if proposed_slot > tip {
|
||||||
|
@ -69,8 +71,8 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
Message::Reconnecting => {
|
||||||
debug!("Stream sent None"); // TODO waht does that mean?
|
warn!("Stream performs reconnect"); // TODO waht does that mean?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue