-
Notifications
You must be signed in to change notification settings - Fork 80
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
Implement shared custom data #428
base: main
Are you sure you want to change the base?
Changes from 4 commits
aa7d8a3
0f3d383
f410d7c
f27bdbf
220bdbe
101193d
fd8012b
d18cb8f
0175908
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ use rust_engineio::{ | |
header::{HeaderMap, HeaderValue}, | ||
}; | ||
use std::collections::HashMap; | ||
use std::sync::Arc; | ||
use url::Url; | ||
|
||
use crate::{error::Result, Event, Payload, TransportType}; | ||
|
@@ -38,6 +39,7 @@ pub struct ClientBuilder { | |
pub(crate) max_reconnect_attempts: Option<u8>, | ||
pub(crate) reconnect_delay_min: u64, | ||
pub(crate) reconnect_delay_max: u64, | ||
pub(crate) data: Option<Arc<dyn std::any::Any + Send + Sync>>, | ||
} | ||
|
||
impl ClientBuilder { | ||
|
@@ -97,9 +99,15 @@ impl ClientBuilder { | |
max_reconnect_attempts: None, | ||
reconnect_delay_min: 1000, | ||
reconnect_delay_max: 5000, | ||
data: None, | ||
} | ||
} | ||
|
||
pub fn data<D: std::any::Any + Send + Sync>(mut self, data: Arc<D>) -> Self { | ||
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. Why already take the Arc? Can't we get a fat pointer? Or does that play out really badly with lifetimes? 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. Please add documentation for the method. IMO this is the perfect place for explaining what data actually is. 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. Yeah! Sure, I mainly forgot to add documentation here honestly. |
||
self.data = Some(data); | ||
self | ||
} | ||
|
||
/// Sets the target namespace of the client. The namespace should start | ||
/// with a leading `/`. Valid examples are e.g. `/admin`, `/foo`. | ||
/// If the String provided doesn't start with a leading `/`, it is | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,6 +74,7 @@ pub struct Client { | |
auth: Option<serde_json::Value>, | ||
builder: Arc<RwLock<ClientBuilder>>, | ||
disconnect_reason: Arc<RwLock<DisconnectReason>>, | ||
data: Arc<dyn std::any::Any + Send + Sync>, | ||
} | ||
|
||
impl Client { | ||
|
@@ -87,11 +88,25 @@ impl Client { | |
nsp: builder.namespace.to_owned(), | ||
outstanding_acks: Arc::new(RwLock::new(Vec::new())), | ||
auth: builder.auth.clone(), | ||
data: builder.data.clone().unwrap_or(Arc::new(())), | ||
builder: Arc::new(RwLock::new(builder)), | ||
disconnect_reason: Arc::new(RwLock::new(DisconnectReason::default())), | ||
}) | ||
} | ||
|
||
/// Fetches data given by [`ClientBuilder::data`] | ||
pub fn data<D: Send + Sync + 'static>(&self) -> Arc<D> { | ||
self.try_data() | ||
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. Panicing in library code is always a risky thing. We rather want controllable errors ( |
||
.expect("Client::data does not match ClientBuilder::data") | ||
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. Mhmmm... I don't really like that we need a runtime check here... Wdyt, would it be possible to make this a generic parameter of both the Client and the builder? If this turns out messy, feel free to omit. 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. Generic parameter was my main concern, sounds like it'd get messy and fast. |
||
} | ||
|
||
/// Attempts to fetch data given by [`ClientBuilder::data`] | ||
/// | ||
/// None is returned if data was not given or data does not match [`ClientBuilder::data`] | ||
pub fn try_data<D: Send + Sync + 'static>(&self) -> Option<Arc<D>> { | ||
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. Mhm, I don't really like the naming here. Usually a 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.
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. Or rather just having a |
||
Arc::clone(&self.data).downcast().ok() | ||
} | ||
|
||
/// Connects the client to a server. Afterwards the `emit_*` methods can be | ||
/// called to interact with the server. | ||
pub(crate) async fn connect(&self) -> Result<()> { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ use std::time::Duration; | |
use std::time::Instant; | ||
|
||
use crate::socket::Socket as InnerSocket; | ||
use crate::asynchronous::ClientBuilder; | ||
|
||
/// Represents an `Ack` as given back to the caller. Holds the internal `id` as | ||
/// well as the current ack'ed state. Holds data which will be accessible as | ||
|
@@ -41,6 +42,7 @@ pub struct RawClient { | |
nsp: String, | ||
// Data send in the opening packet (commonly used as for auth) | ||
auth: Option<Value>, | ||
data: Arc<dyn std::any::Any + Send + Sync>, | ||
} | ||
|
||
impl RawClient { | ||
|
@@ -54,6 +56,7 @@ impl RawClient { | |
on: Arc<Mutex<HashMap<Event, Callback<SocketCallback>>>>, | ||
on_any: Arc<Mutex<Option<Callback<SocketAnyCallback>>>>, | ||
auth: Option<Value>, | ||
data: Arc<dyn std::any::Any + Send + Sync>, | ||
) -> Result<Self> { | ||
Ok(RawClient { | ||
socket, | ||
|
@@ -62,9 +65,23 @@ impl RawClient { | |
on_any, | ||
outstanding_acks: Arc::new(Mutex::new(Vec::new())), | ||
auth, | ||
data, | ||
}) | ||
} | ||
|
||
/// Fetches data given by [`ClientBuilder::data`] | ||
pub fn data<D: Send + Sync + 'static>(&self) -> Arc<D> { | ||
self.try_data() | ||
.expect("RawClient::data does not match ClientBuilder::data") | ||
} | ||
|
||
/// Attempts to fetch data given by [`ClientBuilder::data`] | ||
/// | ||
/// None is returned if data was not given or data does not match [`ClientBuilder::data`] | ||
pub fn try_data<D: Send + Sync + 'static>(&self) -> Option<Arc<D>> { | ||
Arc::clone(&self.data).downcast().ok() | ||
} | ||
|
||
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. Same comments as above! |
||
/// Connects the client to a server. Afterwards the `emit_*` methods can be | ||
/// called to interact with the server. Attention: it's not allowed to add a | ||
/// callback after a call to this method. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Maybe name set_data? Didn't find that this is forbidden according to the naming guidelines this crate uses: https://rust-lang.github.io/api-guidelines/naming.html. Only getters omit the prefix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
set_data sounds good to me.