Skip to content

Commit 7664418

Browse files
authored
feat: seaprate blocking methods (#72)
1 parent f7ff25c commit 7664418

File tree

5 files changed

+166
-68
lines changed

5 files changed

+166
-68
lines changed

relay_client/src/http.rs

+16-18
Original file line numberDiff line numberDiff line change
@@ -142,21 +142,13 @@ impl Client {
142142
/// when fully processed by the relay.
143143
/// Note: This function is experimental and will likely be removed in the
144144
/// future.
145-
pub async fn subscribe_blocking(&self, topic: Topic) -> Response<rpc::Subscribe> {
146-
self.request(rpc::Subscribe { topic, block: true }).await
145+
pub async fn subscribe_blocking(&self, topic: Topic) -> Response<rpc::SubscribeBlocking> {
146+
self.request(rpc::SubscribeBlocking { topic }).await
147147
}
148148

149149
/// Unsubscribes from a topic.
150-
pub async fn unsubscribe(
151-
&self,
152-
topic: Topic,
153-
subscription_id: SubscriptionId,
154-
) -> Response<rpc::Unsubscribe> {
155-
self.request(rpc::Unsubscribe {
156-
topic,
157-
subscription_id,
158-
})
159-
.await
150+
pub async fn unsubscribe(&self, topic: Topic) -> Response<rpc::Unsubscribe> {
151+
self.request(rpc::Unsubscribe { topic }).await
160152
}
161153

162154
/// Fetch mailbox messages for a specific topic.
@@ -265,12 +257,18 @@ impl Client {
265257
pub async fn batch_subscribe_blocking(
266258
&self,
267259
topics: impl Into<Vec<Topic>>,
268-
) -> Response<rpc::BatchSubscribe> {
269-
self.request(rpc::BatchSubscribe {
270-
topics: topics.into(),
271-
block: true,
272-
})
273-
.await
260+
) -> Result<
261+
Vec<Result<SubscriptionId, Error<rpc::SubscriptionError>>>,
262+
Error<rpc::SubscriptionError>,
263+
> {
264+
Ok(self
265+
.request(rpc::BatchSubscribeBlocking {
266+
topics: topics.into(),
267+
})
268+
.await?
269+
.into_iter()
270+
.map(crate::convert_subscription_result)
271+
.collect())
274272
}
275273

276274
/// Unsubscribes from multiple topics.

relay_client/src/lib.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use {
33
::http::HeaderMap,
44
relay_rpc::{
55
auth::{SerializedAuthToken, RELAY_WEBSOCKET_ADDRESS},
6-
domain::{MessageId, ProjectId},
6+
domain::{MessageId, ProjectId, SubscriptionId},
7+
rpc::{SubscriptionError, SubscriptionResult},
78
user_agent::UserAgent,
89
},
910
serde::Serialize,
@@ -170,6 +171,16 @@ impl Default for MessageIdGenerator {
170171
}
171172
}
172173

174+
#[inline]
175+
fn convert_subscription_result(
176+
res: SubscriptionResult,
177+
) -> Result<SubscriptionId, error::Error<SubscriptionError>> {
178+
match res {
179+
SubscriptionResult::Id(id) => Ok(id),
180+
SubscriptionResult::Error(err) => Err(ClientError::from(err).into()),
181+
}
182+
}
183+
173184
#[cfg(test)]
174185
mod tests {
175186
use {

relay_client/src/websocket.rs

+26-17
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
11
use {
22
self::connection::{connection_event_loop, ConnectionControl},
3-
crate::{error::ClientError, ConnectionOptions},
3+
crate::{
4+
error::{ClientError, Error},
5+
ConnectionOptions,
6+
},
47
relay_rpc::{
58
domain::{MessageId, SubscriptionId, Topic},
69
rpc::{
710
BatchFetchMessages,
811
BatchReceiveMessages,
912
BatchSubscribe,
13+
BatchSubscribeBlocking,
1014
BatchUnsubscribe,
1115
FetchMessages,
1216
Publish,
1317
Receipt,
1418
Subscribe,
19+
SubscribeBlocking,
1520
Subscription,
21+
SubscriptionError,
1622
Unsubscribe,
1723
},
1824
},
19-
std::{sync::Arc, time::Duration},
25+
std::{future::Future, sync::Arc, time::Duration},
2026
tokio::sync::{
2127
mpsc::{self, UnboundedSender},
2228
oneshot,
@@ -182,24 +188,17 @@ impl Client {
182188
/// when fully processed by the relay.
183189
/// Note: This function is experimental and will likely be removed in the
184190
/// future.
185-
pub fn subscribe_blocking(&self, topic: Topic) -> ResponseFuture<Subscribe> {
186-
let (request, response) = create_request(Subscribe { topic, block: true });
191+
pub fn subscribe_blocking(&self, topic: Topic) -> ResponseFuture<SubscribeBlocking> {
192+
let (request, response) = create_request(SubscribeBlocking { topic });
187193

188194
self.request(request);
189195

190196
response
191197
}
192198

193199
/// Unsubscribes from a topic.
194-
pub fn unsubscribe(
195-
&self,
196-
topic: Topic,
197-
subscription_id: SubscriptionId,
198-
) -> EmptyResponseFuture<Unsubscribe> {
199-
let (request, response) = create_request(Unsubscribe {
200-
topic,
201-
subscription_id,
202-
});
200+
pub fn unsubscribe(&self, topic: Topic) -> EmptyResponseFuture<Unsubscribe> {
201+
let (request, response) = create_request(Unsubscribe { topic });
203202

204203
self.request(request);
205204

@@ -240,15 +239,25 @@ impl Client {
240239
pub fn batch_subscribe_blocking(
241240
&self,
242241
topics: impl Into<Vec<Topic>>,
243-
) -> ResponseFuture<BatchSubscribe> {
244-
let (request, response) = create_request(BatchSubscribe {
242+
) -> impl Future<
243+
Output = Result<
244+
Vec<Result<SubscriptionId, Error<SubscriptionError>>>,
245+
Error<SubscriptionError>,
246+
>,
247+
> {
248+
let (request, response) = create_request(BatchSubscribeBlocking {
245249
topics: topics.into(),
246-
block: true,
247250
});
248251

249252
self.request(request);
250253

251-
response
254+
async move {
255+
Ok(response
256+
.await?
257+
.into_iter()
258+
.map(crate::convert_subscription_result)
259+
.collect())
260+
}
252261
}
253262

254263
/// Unsubscribes from multiple topics.

relay_rpc/src/rpc.rs

+86-14
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ impl ErrorResponse {
196196
}
197197

198198
/// Data structure representing error response params.
199-
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
199+
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
200200
pub struct ErrorData {
201201
/// Error code.
202202
pub code: i32,
@@ -215,7 +215,9 @@ pub enum SubscriptionError {
215215
SubscriberLimitExceeded,
216216
}
217217

218-
/// Data structure representing subscribe request params.
218+
/// Subscription request parameters. This request does not require the
219+
/// subscription to be fully processed, and returns as soon as the server
220+
/// receives it.
219221
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
220222
pub struct Subscribe {
221223
/// The topic to subscribe to.
@@ -244,15 +246,36 @@ impl ServiceRequest for Subscribe {
244246
}
245247
}
246248

249+
/// Subscription request parameters. This request awaits the subscription to be
250+
/// fully processed and returns possible errors.
251+
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
252+
pub struct SubscribeBlocking {
253+
/// The topic to subscribe to.
254+
pub topic: Topic,
255+
}
256+
257+
impl ServiceRequest for SubscribeBlocking {
258+
type Error = SubscriptionError;
259+
type Response = SubscriptionId;
260+
261+
fn validate(&self) -> Result<(), PayloadError> {
262+
self.topic
263+
.decode()
264+
.map_err(|_| PayloadError::InvalidTopic)?;
265+
266+
Ok(())
267+
}
268+
269+
fn into_params(self) -> Params {
270+
Params::SubscribeBlocking(self)
271+
}
272+
}
273+
247274
/// Data structure representing unsubscribe request params.
248275
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
249276
pub struct Unsubscribe {
250277
/// The topic to unsubscribe from.
251278
pub topic: Topic,
252-
253-
/// The id of the subscription to unsubscribe from.
254-
#[serde(rename = "id")]
255-
pub subscription_id: SubscriptionId,
256279
}
257280

258281
impl ServiceRequest for Unsubscribe {
@@ -317,7 +340,9 @@ pub struct FetchResponse {
317340
pub has_more: bool,
318341
}
319342

320-
/// Multi-topic subscription request parameters.
343+
/// Multi-topic subscription request parameters. This request does not require
344+
/// all subscriptions to be fully processed, and returns as soon as the server
345+
/// receives it.
321346
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
322347
pub struct BatchSubscribe {
323348
/// The topics to subscribe to.
@@ -329,12 +354,9 @@ pub struct BatchSubscribe {
329354
pub block: bool,
330355
}
331356

332-
impl ServiceRequest for BatchSubscribe {
333-
type Error = SubscriptionError;
334-
type Response = Vec<SubscriptionId>;
335-
336-
fn validate(&self) -> Result<(), PayloadError> {
337-
let batch_size = self.topics.len();
357+
impl BatchSubscribe {
358+
fn validate_topics(topics: &[Topic]) -> Result<(), PayloadError> {
359+
let batch_size = topics.len();
338360

339361
if batch_size == 0 {
340362
return Err(PayloadError::BatchEmpty);
@@ -344,18 +366,55 @@ impl ServiceRequest for BatchSubscribe {
344366
return Err(PayloadError::BatchLimitExceeded);
345367
}
346368

347-
for topic in &self.topics {
369+
for topic in topics {
348370
topic.decode().map_err(|_| PayloadError::InvalidTopic)?;
349371
}
350372

351373
Ok(())
352374
}
375+
}
376+
377+
impl ServiceRequest for BatchSubscribe {
378+
type Error = SubscriptionError;
379+
type Response = Vec<SubscriptionId>;
380+
381+
fn validate(&self) -> Result<(), PayloadError> {
382+
Self::validate_topics(&self.topics)
383+
}
353384

354385
fn into_params(self) -> Params {
355386
Params::BatchSubscribe(self)
356387
}
357388
}
358389

390+
/// Multi-topic subscription request parameters. This request awaits all
391+
/// subscriptions to be fully processed and returns possible errors per topic.
392+
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
393+
pub struct BatchSubscribeBlocking {
394+
/// The topics to subscribe to.
395+
pub topics: Vec<Topic>,
396+
}
397+
398+
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
399+
#[serde(rename_all = "camelCase")]
400+
pub enum SubscriptionResult {
401+
Id(SubscriptionId),
402+
Error(ErrorData),
403+
}
404+
405+
impl ServiceRequest for BatchSubscribeBlocking {
406+
type Error = SubscriptionError;
407+
type Response = Vec<SubscriptionResult>;
408+
409+
fn validate(&self) -> Result<(), PayloadError> {
410+
BatchSubscribe::validate_topics(&self.topics)
411+
}
412+
413+
fn into_params(self) -> Params {
414+
Params::BatchSubscribeBlocking(self)
415+
}
416+
}
417+
359418
/// Multi-topic unsubscription request parameters.
360419
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
361420
pub struct BatchUnsubscribe {
@@ -696,6 +755,10 @@ pub enum Params {
696755
#[serde(rename = "irn_subscribe", alias = "iridium_subscribe")]
697756
Subscribe(Subscribe),
698757

758+
/// Parameters to blocking subscribe.
759+
#[serde(rename = "irn_subscribeBlocking", alias = "iridium_subscribeBlocking")]
760+
SubscribeBlocking(SubscribeBlocking),
761+
699762
/// Parameters to unsubscribe.
700763
#[serde(rename = "irn_unsubscribe", alias = "iridium_unsubscribe")]
701764
Unsubscribe(Unsubscribe),
@@ -708,6 +771,13 @@ pub enum Params {
708771
#[serde(rename = "irn_batchSubscribe", alias = "iridium_batchSubscribe")]
709772
BatchSubscribe(BatchSubscribe),
710773

774+
/// Parameters to blocking batch subscribe.
775+
#[serde(
776+
rename = "irn_batchSubscribeBlocking",
777+
alias = "iridium_batchSubscribeBlocking"
778+
)]
779+
BatchSubscribeBlocking(BatchSubscribeBlocking),
780+
711781
/// Parameters to batch unsubscribe.
712782
#[serde(rename = "irn_batchUnsubscribe", alias = "iridium_batchUnsubscribe")]
713783
BatchUnsubscribe(BatchUnsubscribe),
@@ -779,9 +849,11 @@ impl Request {
779849

780850
match &self.params {
781851
Params::Subscribe(params) => params.validate(),
852+
Params::SubscribeBlocking(params) => params.validate(),
782853
Params::Unsubscribe(params) => params.validate(),
783854
Params::FetchMessages(params) => params.validate(),
784855
Params::BatchSubscribe(params) => params.validate(),
856+
Params::BatchSubscribeBlocking(params) => params.validate(),
785857
Params::BatchUnsubscribe(params) => params.validate(),
786858
Params::BatchFetchMessages(params) => params.validate(),
787859
Params::Publish(params) => params.validate(),

0 commit comments

Comments
 (0)