Caching version IDs from the server
This commit is contained in:
parent
0158cfb2d4
commit
0b65dff46d
2 changed files with 25 additions and 2 deletions
|
@ -1,5 +1,6 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use reqwest::header::CONTENT_TYPE;
|
use reqwest::header::CONTENT_TYPE;
|
||||||
|
@ -31,19 +32,23 @@ static TASKS_BODY: &str = r#"
|
||||||
|
|
||||||
|
|
||||||
/// A CalDAV calendar created by a [`Client`](crate::client::Client).
|
/// A CalDAV calendar created by a [`Client`](crate::client::Client).
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct RemoteCalendar {
|
pub struct RemoteCalendar {
|
||||||
name: String,
|
name: String,
|
||||||
resource: Resource,
|
resource: Resource,
|
||||||
supported_components: SupportedComponents,
|
supported_components: SupportedComponents,
|
||||||
|
|
||||||
|
cached_version_tags: Mutex<Option<HashMap<ItemId, VersionTag>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RemoteCalendar {
|
impl RemoteCalendar {
|
||||||
pub fn new(name: String, resource: Resource, supported_components: SupportedComponents) -> Self {
|
pub fn new(name: String, resource: Resource, supported_components: SupportedComponents) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name, resource, supported_components,
|
name, resource, supported_components,
|
||||||
|
cached_version_tags: Mutex::new(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
@ -63,6 +68,11 @@ impl BaseCalendar for RemoteCalendar {
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl DavCalendar for RemoteCalendar {
|
impl DavCalendar for RemoteCalendar {
|
||||||
async fn get_item_version_tags(&self) -> Result<HashMap<ItemId, VersionTag>, Box<dyn Error>> {
|
async fn get_item_version_tags(&self) -> Result<HashMap<ItemId, VersionTag>, Box<dyn Error>> {
|
||||||
|
if let Some(map) = &*self.cached_version_tags.lock().unwrap() {
|
||||||
|
log::debug!("Version tags are already cached.");
|
||||||
|
return Ok(map.clone());
|
||||||
|
};
|
||||||
|
|
||||||
let responses = crate::client::sub_request_and_extract_elems(&self.resource, "REPORT", TASKS_BODY.to_string(), "response").await?;
|
let responses = crate::client::sub_request_and_extract_elems(&self.resource, "REPORT", TASKS_BODY.to_string(), "response").await?;
|
||||||
|
|
||||||
let mut items = HashMap::new();
|
let mut items = HashMap::new();
|
||||||
|
@ -92,6 +102,8 @@ impl DavCalendar for RemoteCalendar {
|
||||||
items.insert(item_id, version_tag);
|
items.insert(item_id, version_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: the mutex cannot be locked during this whole async function, but it can safely be re-entrant (this will just waste an unnecessary request)
|
||||||
|
*self.cached_version_tags.lock().unwrap() = Some(items.clone());
|
||||||
Ok(items)
|
Ok(items)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +117,14 @@ impl DavCalendar for RemoteCalendar {
|
||||||
|
|
||||||
let text = res.text().await?;
|
let text = res.text().await?;
|
||||||
|
|
||||||
let item = crate::ical::parse(&text, id.clone(), SyncStatus::Synced())?;
|
// This is supposed to be cached
|
||||||
|
let version_tags = self.get_item_version_tags().await?;
|
||||||
|
let vt = match version_tags.get(id) {
|
||||||
|
None => return Err(format!("Inconsistent data: {} has no version tag", id).into()),
|
||||||
|
Some(vt) => vt,
|
||||||
|
};
|
||||||
|
|
||||||
|
let item = crate::ical::parse(&text, id.clone(), SyncStatus::Synced(vt.clone()))?;
|
||||||
Ok(Some(item))
|
Ok(Some(item))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,10 @@ impl ItemId{
|
||||||
let u = s.parse().unwrap();
|
let u = s.parse().unwrap();
|
||||||
Self { content:u }
|
Self { content:u }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_url(&self) -> &Url {
|
||||||
|
&self.content
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl From<Url> for ItemId {
|
impl From<Url> for ItemId {
|
||||||
fn from(url: Url) -> Self {
|
fn from(url: Url) -> Self {
|
||||||
|
|
Loading…
Add table
Reference in a new issue