Moved Session inside Arc<>
parent
931523bd20
commit
adf6176a8f
|
@ -21,6 +21,7 @@ async-stream = "0.3"
|
|||
base64 = "0.13"
|
||||
tokio-tungstenite = { version = "0.17", features = ["rustls-tls-webpki-roots"], optional = true}
|
||||
tokio = { version = "1.16", default-features = false, features = ["io-util"], optional = true }
|
||||
parking_lot = "0.12.0"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
@ -28,4 +29,4 @@ websockets = ["tokio", "tokio-tungstenite"]
|
|||
debug = []
|
||||
|
||||
[profile.bench]
|
||||
debug = true
|
||||
debug = true
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use std::{
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
|
@ -20,7 +23,7 @@ use crate::{
|
|||
};
|
||||
|
||||
const DEFAULT_TIMEOUT_MS: u64 = 10 * 1000;
|
||||
static USER_AGENT: &str = concat!("stalwart-jmap/", env!("CARGO_PKG_VERSION"));
|
||||
static USER_AGENT: &str = concat!("jmap-client/", env!("CARGO_PKG_VERSION"));
|
||||
|
||||
pub enum Credentials {
|
||||
Basic(String),
|
||||
|
@ -28,17 +31,21 @@ pub enum Credentials {
|
|||
}
|
||||
|
||||
pub struct Client {
|
||||
session: Session,
|
||||
session: parking_lot::Mutex<Arc<Session>>,
|
||||
session_url: String,
|
||||
api_url: String,
|
||||
session_updated: AtomicBool,
|
||||
#[cfg(feature = "websockets")]
|
||||
pub(crate) authorization: String,
|
||||
|
||||
upload_url: Vec<URLPart<blob::URLParameter>>,
|
||||
download_url: Vec<URLPart<blob::URLParameter>>,
|
||||
event_source_url: Vec<URLPart<event_source::URLParameter>>,
|
||||
timeout: u64,
|
||||
|
||||
headers: header::HeaderMap,
|
||||
default_account_id: String,
|
||||
timeout: u64,
|
||||
|
||||
#[cfg(feature = "websockets")]
|
||||
pub(crate) authorization: String,
|
||||
#[cfg(feature = "websockets")]
|
||||
pub(crate) ws: tokio::sync::Mutex<Option<crate::client_ws::WsStream>>,
|
||||
}
|
||||
|
@ -89,7 +96,8 @@ impl Client {
|
|||
download_url: URLPart::parse(session.download_url())?,
|
||||
upload_url: URLPart::parse(session.upload_url())?,
|
||||
event_source_url: URLPart::parse(session.event_source_url())?,
|
||||
session,
|
||||
api_url: session.api_url().to_string(),
|
||||
session: parking_lot::Mutex::new(Arc::new(session)),
|
||||
session_url: url.to_string(),
|
||||
session_updated: true.into(),
|
||||
#[cfg(feature = "websockets")]
|
||||
|
@ -111,8 +119,8 @@ impl Client {
|
|||
self.timeout
|
||||
}
|
||||
|
||||
pub fn session(&self) -> &Session {
|
||||
&self.session
|
||||
pub fn session(&self) -> Arc<Session> {
|
||||
self.session.lock().clone()
|
||||
}
|
||||
|
||||
pub fn session_url(&self) -> &str {
|
||||
|
@ -136,7 +144,7 @@ impl Client {
|
|||
.timeout(Duration::from_millis(self.timeout))
|
||||
.default_headers(self.headers.clone())
|
||||
.build()?
|
||||
.post(self.session.api_url())
|
||||
.post(&self.api_url)
|
||||
.body(serde_json::to_string(&request)?)
|
||||
.send()
|
||||
.await?,
|
||||
|
@ -146,14 +154,14 @@ impl Client {
|
|||
.await?,
|
||||
)?;
|
||||
|
||||
if response.session_state() != self.session.state() {
|
||||
if response.session_state() != self.session.lock().state() {
|
||||
self.session_updated.store(false, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
pub async fn refresh_session(&mut self) -> crate::Result<()> {
|
||||
pub async fn refresh_session(&self) -> crate::Result<()> {
|
||||
let session: Session = serde_json::from_slice(
|
||||
&Client::handle_error(
|
||||
reqwest::Client::builder()
|
||||
|
@ -168,10 +176,7 @@ impl Client {
|
|||
.bytes()
|
||||
.await?,
|
||||
)?;
|
||||
self.download_url = URLPart::parse(session.download_url())?;
|
||||
self.upload_url = URLPart::parse(session.upload_url())?;
|
||||
self.event_source_url = URLPart::parse(session.event_source_url())?;
|
||||
self.session = session;
|
||||
*self.session.lock() = Arc::new(session);
|
||||
self.session_updated.store(true, Ordering::Relaxed);
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -154,7 +154,8 @@ impl Client {
|
|||
pub async fn connect_ws(
|
||||
&self,
|
||||
) -> crate::Result<Pin<Box<impl Stream<Item = crate::Result<WebSocketMessage>>>>> {
|
||||
let capabilities = self.session().websocket_capabilities().ok_or_else(|| {
|
||||
let session = self.session();
|
||||
let capabilities = session.websocket_capabilities().ok_or_else(|| {
|
||||
crate::Error::Internal(
|
||||
"JMAP server does not advertise any websocket capabilities.".to_string(),
|
||||
)
|
||||
|
|
|
@ -63,7 +63,7 @@ pub struct FilterOperator<T> {
|
|||
conditions: Vec<Filter<T>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
|
||||
pub enum Operator {
|
||||
#[serde(rename = "AND")]
|
||||
And,
|
||||
|
|
|
@ -35,7 +35,7 @@ pub struct Request<'x> {
|
|||
#[serde(skip)]
|
||||
client: &'x Client,
|
||||
#[serde(skip)]
|
||||
default_account_id: String,
|
||||
account_id: String,
|
||||
|
||||
pub using: Vec<URI>,
|
||||
|
||||
|
@ -421,11 +421,16 @@ impl<'x> Request<'x> {
|
|||
using: vec![URI::Core, URI::Mail],
|
||||
method_calls: vec![],
|
||||
created_ids: None,
|
||||
default_account_id: client.default_account_id().to_string(),
|
||||
account_id: client.default_account_id().to_string(),
|
||||
client,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn account_id(mut self, account_id: impl Into<String>) -> Self {
|
||||
self.account_id = account_id.into();
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn send(self) -> crate::Result<Response<TaggedMethodResponse>> {
|
||||
self.client.send(&self).await
|
||||
}
|
||||
|
@ -452,7 +457,7 @@ impl<'x> Request<'x> {
|
|||
|
||||
pub fn params(&self, method: Method) -> RequestParams {
|
||||
RequestParams {
|
||||
account_id: self.default_account_id.clone(),
|
||||
account_id: self.account_id.clone(),
|
||||
method,
|
||||
call_id: self.method_calls.len(),
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use super::Changes;
|
|||
|
||||
impl Client {
|
||||
pub async fn event_source(
|
||||
&mut self,
|
||||
&self,
|
||||
mut types: Option<impl IntoIterator<Item = TypeState>>,
|
||||
close_after_state: bool,
|
||||
ping: Option<u32>,
|
||||
|
|
|
@ -13,8 +13,8 @@ impl Mailbox<Get> {
|
|||
self.id.unwrap()
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
self.name.as_ref().unwrap()
|
||||
pub fn name(&self) -> Option<&str> {
|
||||
self.name.as_deref()
|
||||
}
|
||||
|
||||
pub fn parent_id(&self) -> Option<&str> {
|
||||
|
|
|
@ -96,7 +96,7 @@ pub struct Mailbox<State = Get> {
|
|||
acl_patch: Option<HashMap<String, Vec<ACL>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum Role {
|
||||
#[serde(rename = "archive", alias = "ARCHIVE")]
|
||||
|
|
Loading…
Reference in New Issue