Share UniqueIdent between collections
This commit is contained in:
parent
22e4f29555
commit
ed47855ef1
15 changed files with 90 additions and 17 deletions
|
@ -1 +1,5 @@
|
|||
//@FIXME Event Index
|
||||
pub mod namespace;
|
||||
|
||||
pub struct Calendar {
|
||||
a: u64,
|
||||
}
|
||||
|
|
47
aero-collections/src/calendar/namespace.rs
Normal file
47
aero-collections/src/calendar/namespace.rs
Normal file
|
@ -0,0 +1,47 @@
|
|||
use anyhow::Result;
|
||||
use std::collections::{HashMap, BTreeMap};
|
||||
use std::sync::{Weak, Arc};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use aero_user::storage;
|
||||
|
||||
use crate::unique_ident::UniqueIdent;
|
||||
use crate::user::User;
|
||||
use super::Calendar;
|
||||
|
||||
pub(crate) const CAL_LIST_PK: &str = "calendars";
|
||||
pub(crate) const CAL_LIST_SK: &str = "list";
|
||||
|
||||
pub(crate) struct CalendarNs(std::sync::Mutex<HashMap<UniqueIdent, Weak<Calendar>>>);
|
||||
impl CalendarNs {
|
||||
pub fn new() -> Self {
|
||||
Self(std::sync::Mutex::new(HashMap::new()))
|
||||
}
|
||||
|
||||
pub fn list(&self) {
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub(crate) struct CalendarList(BTreeMap<String, CalendarListEntry>);
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug)]
|
||||
pub(crate) struct CalendarListEntry {
|
||||
id_lww: (u64, Option<UniqueIdent>),
|
||||
}
|
||||
|
||||
impl CalendarList {
|
||||
pub(crate) async fn load(user: &Arc<User>) -> Result<(Self, Option<storage::RowRef>)> {
|
||||
todo!();
|
||||
}
|
||||
|
||||
pub(crate) async fn save(user: &Arc<User>, ct: Option<storage::RowRef>) -> Result<()> {
|
||||
todo!();
|
||||
}
|
||||
|
||||
pub(crate) fn new() -> Self {
|
||||
Self(BTreeMap::new())
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
pub mod unique_ident;
|
||||
pub mod user;
|
||||
pub mod mail;
|
||||
pub mod calendar;
|
||||
|
|
|
@ -15,7 +15,7 @@ use aero_bayou::timestamp::now_msec;
|
|||
|
||||
use crate::mail::mailbox::Mailbox;
|
||||
use crate::mail::uidindex::ImapUidvalidity;
|
||||
use crate::mail::unique_ident::*;
|
||||
use crate::unique_ident::*;
|
||||
use crate::user::User;
|
||||
use crate::mail::IMF;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ use aero_bayou::Bayou;
|
|||
use aero_bayou::timestamp::now_msec;
|
||||
|
||||
use crate::mail::uidindex::*;
|
||||
use crate::mail::unique_ident::*;
|
||||
use crate::unique_ident::*;
|
||||
use crate::mail::IMF;
|
||||
|
||||
pub struct Mailbox {
|
||||
|
|
|
@ -3,7 +3,6 @@ pub mod mailbox;
|
|||
pub mod query;
|
||||
pub mod snapshot;
|
||||
pub mod uidindex;
|
||||
pub mod unique_ident;
|
||||
pub mod namespace;
|
||||
|
||||
// Internet Message Format
|
||||
|
|
|
@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
|
|||
use aero_bayou::timestamp::now_msec;
|
||||
|
||||
use crate::mail::uidindex::ImapUidvalidity;
|
||||
use crate::mail::unique_ident::{gen_ident, UniqueIdent};
|
||||
use crate::unique_ident::{gen_ident, UniqueIdent};
|
||||
|
||||
pub const MAILBOX_HIERARCHY_DELIMITER: char = '.';
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use super::mailbox::MailMeta;
|
||||
use super::snapshot::FrozenMailbox;
|
||||
use super::unique_ident::UniqueIdent;
|
||||
use crate::unique_ident::UniqueIdent;
|
||||
use anyhow::Result;
|
||||
use futures::future::FutureExt;
|
||||
use futures::stream::{BoxStream, Stream, StreamExt};
|
||||
|
|
|
@ -2,10 +2,10 @@ use std::sync::Arc;
|
|||
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::unique_ident::UniqueIdent;
|
||||
use super::mailbox::Mailbox;
|
||||
use super::query::{Query, QueryScope};
|
||||
use super::uidindex::UidIndex;
|
||||
use super::unique_ident::UniqueIdent;
|
||||
|
||||
/// A Frozen Mailbox has a snapshot of the current mailbox
|
||||
/// state that is desynchronized with the real mailbox state.
|
||||
|
|
|
@ -4,7 +4,7 @@ use im::{HashMap, OrdMap, OrdSet};
|
|||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use aero_bayou::*;
|
||||
use crate::mail::unique_ident::UniqueIdent;
|
||||
use crate::unique_ident::UniqueIdent;
|
||||
|
||||
pub type ModSeq = NonZeroU64;
|
||||
pub type ImapUid = NonZeroU32;
|
||||
|
|
|
@ -7,7 +7,7 @@ use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
|
|||
|
||||
use aero_bayou::timestamp::now_msec;
|
||||
|
||||
/// An internal Mail Identifier is composed of two components:
|
||||
/// An internal Aerogramme identifier is composed of two components:
|
||||
/// - a process identifier, 128 bits, itself composed of:
|
||||
/// - the timestamp of when the process started, 64 bits
|
||||
/// - a 64-bit random number
|
||||
|
@ -15,7 +15,7 @@ use aero_bayou::timestamp::now_msec;
|
|||
/// They are not part of the protocol but an internal representation
|
||||
/// required by Aerogramme.
|
||||
/// Their main property is to be unique without having to rely
|
||||
/// on synchronization between IMAP processes.
|
||||
/// on synchronization between (IMAP) processes.
|
||||
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
|
||||
pub struct UniqueIdent(pub [u8; 24]);
|
||||
|
|
@ -12,19 +12,27 @@ use aero_user::storage;
|
|||
use crate::mail::incoming::incoming_mail_watch_process;
|
||||
use crate::mail::mailbox::Mailbox;
|
||||
use crate::mail::uidindex::ImapUidvalidity;
|
||||
use crate::mail::unique_ident::UniqueIdent;
|
||||
use crate::unique_ident::UniqueIdent;
|
||||
use crate::mail::namespace::{MAILBOX_HIERARCHY_DELIMITER, INBOX, DRAFTS, ARCHIVE, SENT, TRASH, MAILBOX_LIST_PK, MAILBOX_LIST_SK,MailboxList,CreatedMailbox};
|
||||
use crate::calendar::Calendar;
|
||||
|
||||
//@FIXME User should be totally rewriten
|
||||
// to extract the local mailbox list
|
||||
// to the mail/namespace.rs file (and mailbox list should be reworded as mail namespace)
|
||||
|
||||
//@FIXME User should be run in a LocalSet
|
||||
// to remove most - if not all - synchronizations types.
|
||||
// Especially RwLock & co.
|
||||
|
||||
pub struct User {
|
||||
pub username: String,
|
||||
pub creds: Credentials,
|
||||
pub storage: storage::Store,
|
||||
pub mailboxes: std::sync::Mutex<HashMap<UniqueIdent, Weak<Mailbox>>>,
|
||||
pub calendars: std::sync::Mutex<HashMap<UniqueIdent, Weak<Calendar>>>,
|
||||
|
||||
// Handle on worker processing received email
|
||||
// (moving emails from the mailqueue to the user's INBOX)
|
||||
tx_inbox_id: watch::Sender<Option<(UniqueIdent, ImapUidvalidity)>>,
|
||||
}
|
||||
|
||||
|
@ -178,6 +186,7 @@ impl User {
|
|||
storage,
|
||||
tx_inbox_id,
|
||||
mailboxes: std::sync::Mutex::new(HashMap::new()),
|
||||
calendars: std::sync::Mutex::new(HashMap::new()),
|
||||
});
|
||||
|
||||
// Ensure INBOX exists (done inside load_mailbox_list)
|
||||
|
@ -204,6 +213,10 @@ impl User {
|
|||
}
|
||||
}
|
||||
|
||||
// The idea here is that:
|
||||
// 1. Opening a mailbox that is not already opened takes a significant amount of time
|
||||
// 2. We don't want to lock the whole HashMap that contain the mailboxes during this
|
||||
// operation which is why we droppped the lock above but take it again below.
|
||||
let mb = Arc::new(Mailbox::open(&self.creds, id, min_uidvalidity).await?);
|
||||
|
||||
let mut cache = self.mailboxes.lock().unwrap();
|
||||
|
|
|
@ -27,6 +27,8 @@ use aero_dav::acltypes as acl;
|
|||
use aero_dav::realization::{All, self as all};
|
||||
use aero_dav::xml as dxml;
|
||||
|
||||
type ArcUser = std::sync::Arc<User>;
|
||||
|
||||
pub struct Server {
|
||||
bind_addr: SocketAddr,
|
||||
login_provider: ArcLoginProvider,
|
||||
|
@ -359,7 +361,15 @@ async fn propfind(user: std::sync::Arc<User>, req: Request<Incoming>, base_node:
|
|||
async fn report(user: std::sync::Arc<User>, req: Request<Incoming>, node: Box<dyn DavNode>) -> Result<Response<BoxBody<Bytes, std::io::Error>>> {
|
||||
let status = hyper::StatusCode::from_u16(207)?;
|
||||
|
||||
let report = deserialize::<cal::Report<All>>(req).await?;
|
||||
let report = match deserialize::<cal::Report<All>>(req).await {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
tracing::error!(err=?e, "unable to decode REPORT body");
|
||||
return Ok(Response::builder()
|
||||
.status(400)
|
||||
.body(text_body("Bad request"))?)
|
||||
}
|
||||
};
|
||||
|
||||
// Multiget is really like a propfind where Depth: 0|1|Infinity is replaced by an arbitrary
|
||||
// list of URLs
|
||||
|
@ -492,7 +502,6 @@ async fn deserialize<T: dxml::Node<T>>(req: Request<Incoming>) -> Result<T> {
|
|||
|
||||
//---
|
||||
|
||||
type ArcUser = std::sync::Arc<User>;
|
||||
trait DavNode: Send {
|
||||
// ------- specialized logic
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use anyhow::{anyhow, Result};
|
|||
use imap_codec::imap_types::sequence::{SeqOrUid, Sequence, SequenceSet};
|
||||
|
||||
use aero_collections::mail::uidindex::{ImapUid, ModSeq, UidIndex};
|
||||
use aero_collections::mail::unique_ident::UniqueIdent;
|
||||
use aero_collections::unique_ident::UniqueIdent;
|
||||
|
||||
pub struct Index<'a> {
|
||||
pub imap_index: Vec<MailIndex<'a>>,
|
||||
|
|
|
@ -17,7 +17,7 @@ use aero_collections::mail::mailbox::Mailbox;
|
|||
use aero_collections::mail::query::QueryScope;
|
||||
use aero_collections::mail::snapshot::FrozenMailbox;
|
||||
use aero_collections::mail::uidindex::{ImapUid, ImapUidvalidity, ModSeq};
|
||||
use aero_collections::mail::unique_ident::UniqueIdent;
|
||||
use aero_collections::unique_ident::UniqueIdent;
|
||||
|
||||
use crate::imap::attributes::AttributesProxy;
|
||||
use crate::imap::flags;
|
||||
|
|
Loading…
Reference in a new issue