Skip to content

Commit 3852195

Browse files
authored
fix: feed rpc responses and notifications instead of send and flush (#135)
* fix: feed rpc respones and notifications instead of send and flush * refactor: use duration instead of _secs in config * chore: bump version
1 parent efc17f5 commit 3852195

File tree

6 files changed

+53
-22
lines changed

6 files changed

+53
-22
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pyth-agent"
3-
version = "2.10.2"
3+
version = "2.10.3"
44
edition = "2021"
55

66
[[bin]]

config/config.toml

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@
66
# connection is not exposed for unauthorized access.
77
listen_address = "127.0.0.1:8910"
88

9+
# Size of the buffer of each Server's channel on which `notify_price` events are
10+
# received from the Price state.
11+
# notify_price_tx_buffer = 10000
12+
13+
# Size of the buffer of each Server's channel on which `notify_price_sched` events are
14+
# received from the Price state.
15+
# notify_price_sched_tx_buffer = 10000
16+
17+
# Flush interval for responses and notifications. This is the maximum time the
18+
# server will wait before flushing the messages to the client.
19+
# flush_interval_duration = "50ms"
20+
921
# Configuration for the primary network this agent will publish data to. In most cases this should be a Pythnet endpoint.
1022
[primary_network]
1123
### Required fields ###
@@ -186,8 +198,8 @@ key_store.mapping_key = "RelevantOracleMappingAddress"
186198
## Configuration for OpenTelemetry ##
187199
[opentelemetry]
188200

189-
# Timeout in seconds for the OpenTelemetry exporter
190-
exporter_timeout_secs = 3
201+
# Timeout duration for the OpenTelemetry exporter
202+
exporter_timeout_duration = "3s"
191203

192204
# Endpoint URL for the OpenTelemetry exporter
193205
exporter_endpoint = "http://127.0.0.1:4317"

src/agent/config.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ use {
1313
File,
1414
},
1515
serde::Deserialize,
16-
std::path::Path,
16+
std::{
17+
path::Path,
18+
time::Duration,
19+
},
1720
};
1821

1922
/// Configuration for all components of the Agent
@@ -88,6 +91,7 @@ impl Default for ChannelCapacities {
8891

8992
#[derive(Deserialize, Debug)]
9093
pub struct OpenTelemetryConfig {
91-
pub exporter_timeout_secs: u64,
92-
pub exporter_endpoint: String,
94+
#[serde(with = "humantime_serde")]
95+
pub exporter_timeout_duration: Duration,
96+
pub exporter_endpoint: String,
9397
}

src/agent/pyth/rpc.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ use {
4848
fmt::Debug,
4949
net::SocketAddr,
5050
sync::Arc,
51+
time::Duration,
5152
},
5253
tokio::sync::mpsc,
5354
tracing::instrument,
@@ -115,6 +116,7 @@ async fn handle_connection<S>(
115116
state: Arc<S>,
116117
notify_price_tx_buffer: usize,
117118
notify_price_sched_tx_buffer: usize,
119+
flush_interval_duration: Duration,
118120
) where
119121
S: state::Prices,
120122
S: Send,
@@ -127,6 +129,8 @@ async fn handle_connection<S>(
127129
let (mut notify_price_sched_tx, mut notify_price_sched_rx) =
128130
mpsc::channel(notify_price_sched_tx_buffer);
129131

132+
let mut flush_interval = tokio::time::interval(flush_interval_duration);
133+
130134
loop {
131135
if let Err(err) = handle_next(
132136
&*state,
@@ -136,6 +140,7 @@ async fn handle_connection<S>(
136140
&mut notify_price_rx,
137141
&mut notify_price_sched_tx,
138142
&mut notify_price_sched_rx,
143+
&mut flush_interval,
139144
)
140145
.await
141146
{
@@ -159,6 +164,7 @@ async fn handle_next<S>(
159164
notify_price_rx: &mut mpsc::Receiver<NotifyPrice>,
160165
notify_price_sched_tx: &mut mpsc::Sender<NotifyPriceSched>,
161166
notify_price_sched_rx: &mut mpsc::Receiver<NotifyPriceSched>,
167+
flush_interval: &mut tokio::time::Interval,
162168
) -> Result<()>
163169
where
164170
S: state::Prices,
@@ -183,13 +189,16 @@ where
183189
}
184190
}
185191
Some(notify_price) = notify_price_rx.recv() => {
186-
send_notification(ws_tx, Method::NotifyPrice, Some(notify_price))
192+
feed_notification(ws_tx, Method::NotifyPrice, Some(notify_price))
187193
.await
188194
}
189195
Some(notify_price_sched) = notify_price_sched_rx.recv() => {
190-
send_notification(ws_tx, Method::NotifyPriceSched, Some(notify_price_sched))
196+
feed_notification(ws_tx, Method::NotifyPriceSched, Some(notify_price_sched))
191197
.await
192198
}
199+
_ = flush_interval.tick() => {
200+
flush(ws_tx).await
201+
}
193202
}
194203
}
195204

@@ -229,9 +238,9 @@ where
229238
// Send an array if we're handling a batch
230239
// request, single response object otherwise
231240
if is_batch {
232-
send_text(ws_tx, &serde_json::to_string(&responses)?).await?;
241+
feed_text(ws_tx, &serde_json::to_string(&responses)?).await?;
233242
} else {
234-
send_text(ws_tx, &serde_json::to_string(&responses[0])?).await?;
243+
feed_text(ws_tx, &serde_json::to_string(&responses[0])?).await?;
235244
}
236245
}
237246
// The top-level parsing errors are fine to share with client
@@ -354,21 +363,21 @@ async fn send_error(
354363
error.to_string(),
355364
None,
356365
);
357-
send_text(ws_tx, &response.to_string()).await
366+
feed_text(ws_tx, &response.to_string()).await
358367
}
359368

360-
async fn send_notification<T>(
369+
async fn feed_notification<T>(
361370
ws_tx: &mut SplitSink<WebSocket, Message>,
362371
method: Method,
363372
params: Option<T>,
364373
) -> Result<()>
365374
where
366375
T: Sized + Serialize + DeserializeOwned,
367376
{
368-
send_request(ws_tx, IdReq::Notification, method, params).await
377+
feed_request(ws_tx, IdReq::Notification, method, params).await
369378
}
370379

371-
async fn send_request<I, T>(
380+
async fn feed_request<I, T>(
372381
ws_tx: &mut SplitSink<WebSocket, Message>,
373382
id: I,
374383
method: Method,
@@ -379,16 +388,20 @@ where
379388
T: Sized + Serialize + DeserializeOwned,
380389
{
381390
let request = Request::with_params(id, method, params);
382-
send_text(ws_tx, &request.to_string()).await
391+
feed_text(ws_tx, &request.to_string()).await
383392
}
384393

385-
async fn send_text(ws_tx: &mut SplitSink<WebSocket, Message>, msg: &str) -> Result<()> {
394+
async fn feed_text(ws_tx: &mut SplitSink<WebSocket, Message>, msg: &str) -> Result<()> {
386395
ws_tx
387-
.send(Message::text(msg.to_string()))
396+
.feed(Message::text(msg.to_string()))
388397
.await
389398
.map_err(|e| e.into())
390399
}
391400

401+
async fn flush(ws_tx: &mut SplitSink<WebSocket, Message>) -> Result<()> {
402+
ws_tx.flush().await.map_err(|e| e.into())
403+
}
404+
392405
#[derive(Clone, Debug, Serialize, Deserialize)]
393406
#[serde(default)]
394407
pub struct Config {
@@ -400,6 +413,9 @@ pub struct Config {
400413
/// Size of the buffer of each Server's channel on which `notify_price_sched` events are
401414
/// received from the Price state.
402415
pub notify_price_sched_tx_buffer: usize,
416+
/// Flush interval duration for the notifications.
417+
#[serde(with = "humantime_serde")]
418+
pub flush_interval_duration: Duration,
403419
}
404420

405421
impl Default for Config {
@@ -408,6 +424,7 @@ impl Default for Config {
408424
listen_address: "127.0.0.1:8910".to_string(),
409425
notify_price_tx_buffer: 10000,
410426
notify_price_sched_tx_buffer: 10000,
427+
flush_interval_duration: Duration::from_millis(50),
411428
}
412429
}
413430
}
@@ -448,6 +465,7 @@ where
448465
state,
449466
config.notify_price_tx_buffer,
450467
config.notify_price_sched_tx_buffer,
468+
config.flush_interval_duration,
451469
)
452470
.await
453471
})

src/bin/agent.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use {
1414
std::{
1515
io::IsTerminal,
1616
path::PathBuf,
17-
time::Duration,
1817
},
1918
tracing_subscriber::{
2019
prelude::*,
@@ -65,9 +64,7 @@ async fn main() -> Result<()> {
6564
let otlp_exporter = opentelemetry_otlp::new_exporter()
6665
.tonic()
6766
.with_endpoint(&opentelemetry_config.exporter_endpoint)
68-
.with_timeout(Duration::from_secs(
69-
opentelemetry_config.exporter_timeout_secs,
70-
));
67+
.with_timeout(opentelemetry_config.exporter_timeout_duration);
7168

7269
// Set up the OpenTelemetry tracer
7370
let tracer = opentelemetry_otlp::new_pipeline()

0 commit comments

Comments
 (0)