Conversation
…t event when flushing
… thruth. - Add a log when not receiving data, so we know when richat / grpc source is idle for better observability
| let update = if idle_warn_secs == 0 { | ||
| match stream.next().await { | ||
| Some(update) => update, | ||
| None => break SourceExitStatus::StreamEnded, | ||
| } | ||
| } else { | ||
| match tokio::time::timeout(stream_idle_timeout, stream.next()).await { |
There was a problem hiding this comment.
This doesn't smell normal. The grpc client sends ping requests if you are seeing idle connections that is more likely an issue with the grpc source.
There was a problem hiding this comment.
Yes i agree, i use https://richat.juprpc.com as source.
For the context, I configured it to 2s (since i'm always supposed to receive data pretty quick e.g slot update status is minimum every 400ms at worst) but it happened 100 times last night and the stream resumed only 95 times so it shows a problem not detected by the ping.
So we have some kind of lag highlighted through this. I don't know where in the chain it happens (load balancer or lag from_slot memory fetch etc...) tho, need to investigate properly.
crates/kafka-sink/src/handler.rs
Outdated
| } | ||
| } | ||
|
|
||
| fn check_send<T>(&self, result: Result<(), tokio::sync::mpsc::error::SendError<T>>) { |
There was a problem hiding this comment.
| fn check_send<T>(&self, result: Result<(), tokio::sync::mpsc::error::SendError<T>>) { | |
| fn cancelable_send<T>(&self, result: Result<(), tokio::sync::mpsc::error::SendError<T>>) { |
More expressive than check?
There was a problem hiding this comment.
Yes i like it too, will change
| } | ||
|
|
||
| #[derive(Debug)] | ||
| struct MockSourceExitStreamErrorSource; |
| impl SourceTrait for MockSourceExitStreamErrorSource { | ||
| type Config = NullConfig; | ||
|
|
||
| fn new(_: NullConfig, _: vixen_core::Filters) -> Self { Self } |
There was a problem hiding this comment.
Can the new be a trait level method so doesn't need to be defined on each source trait? Something for later but always bugged me having to define the new when its inferable from the Config type declartion.
There was a problem hiding this comment.
I check about it
There was a problem hiding this comment.
So actually if we put the new in the trait, we would have to do
impl From<(MyConfig, Filters)> for MySource {
fn from((config, filters): (MyConfig, Filters)) -> Self {
Self { config, filters }
}
}
impl SourceTrait for MySource {
type Config = MyConfig;
async fn connect(...) -> Result<(), Error> { ... }
}
instead of now having
impl SourceTrait for MySource {
type Config = MyConfig;
fn new(config: Self::Config, filters: Filters) -> Self {
Self { config, filters }
}
async fn connect(...) -> Result<(), Error> { ... }
}
which doesn't seem a big gain.
I guess we could add a derive macro (have to be careful on field order for the tuple conversion though).
use derive_more::From;
#[derive(Debug, From)]
pub struct YellowstoneGrpcSource {
config: YellowstoneGrpcConfig,
filters: Filters,
}
#[async_trait]
impl SourceTrait for YellowstoneGrpcSource {
type Config = YellowstoneGrpcConfig;
async fn connect(...) -> Result<(), VixenError> { ... }
}
Seems a lot of headache anyway (and breaking change existing impl of SourceTrait)...
Runtime
Kafka-sink
Block-coordinator