Moved Session inside Arc<>

main
Mauro D 2022-07-05 18:10:32 +00:00
parent 931523bd20
commit adf6176a8f
8 changed files with 38 additions and 26 deletions

View File

@ -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

View File

@ -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(())
}

View File

@ -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(),
)

View File

@ -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,

View File

@ -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(),
}

View File

@ -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>,

View File

@ -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> {

View File

@ -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")]