mirror of
https://github.com/chatmail/core.git
synced 2026-04-27 10:26:29 +03:00
Emit events from account manager
Errors and warnings are emitted with a special 0 account ID.
This commit is contained in:
@@ -4993,7 +4993,7 @@ char* dc_event_get_data2_str(dc_event_t* event);
|
||||
*
|
||||
* @memberof dc_event_t
|
||||
* @param event Event object as returned from dc_accounts_get_next_event().
|
||||
* @return account-id belonging to the event or 0 for errors.
|
||||
* @return account-id belonging to the event, 0 for account manager errors.
|
||||
*/
|
||||
uint32_t dc_event_get_account_id(dc_event_t* event);
|
||||
|
||||
|
||||
@@ -3856,9 +3856,19 @@ pub unsafe extern "C" fn dc_accounts_select_account(
|
||||
}
|
||||
|
||||
let accounts = &*accounts;
|
||||
block_on(async move { accounts.write().await.select_account(id).await })
|
||||
.map(|_| 1)
|
||||
.unwrap_or(0)
|
||||
block_on(async move {
|
||||
let mut accounts = accounts.write().await;
|
||||
match accounts.select_account(id).await {
|
||||
Ok(()) => 1,
|
||||
Err(err) => {
|
||||
accounts.emit_event(EventType::Error(format!(
|
||||
"Failed to select account: {:#}",
|
||||
err
|
||||
)));
|
||||
0
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -3870,7 +3880,19 @@ pub unsafe extern "C" fn dc_accounts_add_account(accounts: *mut dc_accounts_t) -
|
||||
|
||||
let accounts = &mut *accounts;
|
||||
|
||||
block_on(async move { accounts.write().await.add_account().await }).unwrap_or(0)
|
||||
block_on(async move {
|
||||
let mut accounts = accounts.write().await;
|
||||
match accounts.add_account().await {
|
||||
Ok(id) => id,
|
||||
Err(err) => {
|
||||
accounts.emit_event(EventType::Error(format!(
|
||||
"Failed to add account: {:#}",
|
||||
err
|
||||
)));
|
||||
0
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -3885,9 +3907,19 @@ pub unsafe extern "C" fn dc_accounts_remove_account(
|
||||
|
||||
let accounts = &mut *accounts;
|
||||
|
||||
block_on(async move { accounts.write().await.remove_account(id).await })
|
||||
.map(|_| 1)
|
||||
.unwrap_or_else(|_| 0)
|
||||
block_on(async move {
|
||||
let mut accounts = accounts.write().await;
|
||||
match accounts.remove_account(id).await {
|
||||
Ok(()) => 1,
|
||||
Err(err) => {
|
||||
accounts.emit_event(EventType::Error(format!(
|
||||
"Failed to remove account: {:#}",
|
||||
err
|
||||
)));
|
||||
0
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -3904,14 +3936,21 @@ pub unsafe extern "C" fn dc_accounts_migrate_account(
|
||||
let dbfile = to_string_lossy(dbfile);
|
||||
|
||||
block_on(async move {
|
||||
accounts
|
||||
.write()
|
||||
.await
|
||||
let mut accounts = accounts.write().await;
|
||||
match accounts
|
||||
.migrate_account(async_std::path::PathBuf::from(dbfile))
|
||||
.await
|
||||
{
|
||||
Ok(id) => id,
|
||||
Err(err) => {
|
||||
accounts.emit_event(EventType::Error(format!(
|
||||
"Failed to migrate account: {:#}",
|
||||
err
|
||||
)));
|
||||
0
|
||||
}
|
||||
}
|
||||
})
|
||||
.map(|_| 1)
|
||||
.unwrap_or_else(|_| 0)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
@@ -13,7 +13,7 @@ use anyhow::{ensure, Context as _, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::context::Context;
|
||||
use crate::events::Event;
|
||||
use crate::events::{Event, EventType, Events};
|
||||
|
||||
/// Account manager, that can handle multiple accounts in a single place.
|
||||
#[derive(Debug)]
|
||||
@@ -23,12 +23,8 @@ pub struct Accounts {
|
||||
accounts: BTreeMap<u32, Context>,
|
||||
emitter: EventEmitter,
|
||||
|
||||
/// Sender side of the fake event channel.
|
||||
///
|
||||
/// We never send any events over this channel, but hold it during the account manager lifetime
|
||||
/// to prevent `EventEmitter` from returning `None` as long as account manager is alive, even if
|
||||
/// it holds no accounts which could emit events.
|
||||
fake_sender: Sender<crate::events::Event>,
|
||||
/// Event channel to emit account manager errors.
|
||||
events: Events,
|
||||
}
|
||||
|
||||
impl Accounts {
|
||||
@@ -65,9 +61,9 @@ impl Accounts {
|
||||
|
||||
let emitter = EventEmitter::new();
|
||||
|
||||
// Fake event stream to prevent event emitter from closing.
|
||||
let (fake_sender, fake_receiver) = channel::bounded(1);
|
||||
emitter.sender.send(fake_receiver).await?;
|
||||
let events = Events::default();
|
||||
|
||||
emitter.sender.send(events.get_emitter()).await?;
|
||||
|
||||
for account in accounts.values() {
|
||||
emitter.add_account(account).await?;
|
||||
@@ -78,7 +74,7 @@ impl Accounts {
|
||||
config,
|
||||
accounts,
|
||||
emitter,
|
||||
fake_sender,
|
||||
events,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -262,6 +258,11 @@ impl Accounts {
|
||||
}
|
||||
}
|
||||
|
||||
/// Emits a single event.
|
||||
pub fn emit_event(&self, event: EventType) {
|
||||
self.events.emit(Event { id: 0, typ: event })
|
||||
}
|
||||
|
||||
/// Returns unified event emitter.
|
||||
pub async fn get_event_emitter(&self) -> EventEmitter {
|
||||
self.emitter.clone()
|
||||
@@ -272,13 +273,13 @@ impl Accounts {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EventEmitter {
|
||||
/// Aggregate stream of events from all accounts.
|
||||
stream: Arc<RwLock<futures::stream::SelectAll<Receiver<crate::events::Event>>>>,
|
||||
stream: Arc<RwLock<futures::stream::SelectAll<crate::events::EventEmitter>>>,
|
||||
|
||||
/// Sender for the channel where new account emitters will be pushed.
|
||||
sender: Sender<Receiver<crate::events::Event>>,
|
||||
sender: Sender<crate::events::EventEmitter>,
|
||||
|
||||
/// Receiver for the channel where new account emitters will be pushed.
|
||||
receiver: Receiver<Receiver<crate::events::Event>>,
|
||||
receiver: Receiver<crate::events::EventEmitter>,
|
||||
}
|
||||
|
||||
impl EventEmitter {
|
||||
@@ -311,9 +312,7 @@ impl EventEmitter {
|
||||
|
||||
/// Add event emitter of a new account to the aggregate event emitter.
|
||||
pub async fn add_account(&self, context: &Context) -> Result<()> {
|
||||
self.sender
|
||||
.send(context.get_event_emitter().into_inner())
|
||||
.await?;
|
||||
self.sender.send(context.get_event_emitter()).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,10 +62,6 @@ impl Events {
|
||||
pub struct EventEmitter(Receiver<Event>);
|
||||
|
||||
impl EventEmitter {
|
||||
pub(crate) fn into_inner(self) -> Receiver<Event> {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Blocking recv of an event. Return `None` if the `Sender` has been droped.
|
||||
pub fn recv_sync(&self) -> Option<Event> {
|
||||
async_std::task::block_on(self.recv())
|
||||
|
||||
Reference in New Issue
Block a user