mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 17:36: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
|
* @memberof dc_event_t
|
||||||
* @param event Event object as returned from dc_accounts_get_next_event().
|
* @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);
|
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;
|
let accounts = &*accounts;
|
||||||
block_on(async move { accounts.write().await.select_account(id).await })
|
block_on(async move {
|
||||||
.map(|_| 1)
|
let mut accounts = accounts.write().await;
|
||||||
.unwrap_or(0)
|
match accounts.select_account(id).await {
|
||||||
|
Ok(()) => 1,
|
||||||
|
Err(err) => {
|
||||||
|
accounts.emit_event(EventType::Error(format!(
|
||||||
|
"Failed to select account: {:#}",
|
||||||
|
err
|
||||||
|
)));
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -3870,7 +3880,19 @@ pub unsafe extern "C" fn dc_accounts_add_account(accounts: *mut dc_accounts_t) -
|
|||||||
|
|
||||||
let accounts = &mut *accounts;
|
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]
|
#[no_mangle]
|
||||||
@@ -3885,9 +3907,19 @@ pub unsafe extern "C" fn dc_accounts_remove_account(
|
|||||||
|
|
||||||
let accounts = &mut *accounts;
|
let accounts = &mut *accounts;
|
||||||
|
|
||||||
block_on(async move { accounts.write().await.remove_account(id).await })
|
block_on(async move {
|
||||||
.map(|_| 1)
|
let mut accounts = accounts.write().await;
|
||||||
.unwrap_or_else(|_| 0)
|
match accounts.remove_account(id).await {
|
||||||
|
Ok(()) => 1,
|
||||||
|
Err(err) => {
|
||||||
|
accounts.emit_event(EventType::Error(format!(
|
||||||
|
"Failed to remove account: {:#}",
|
||||||
|
err
|
||||||
|
)));
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -3904,14 +3936,21 @@ pub unsafe extern "C" fn dc_accounts_migrate_account(
|
|||||||
let dbfile = to_string_lossy(dbfile);
|
let dbfile = to_string_lossy(dbfile);
|
||||||
|
|
||||||
block_on(async move {
|
block_on(async move {
|
||||||
accounts
|
let mut accounts = accounts.write().await;
|
||||||
.write()
|
match accounts
|
||||||
.await
|
|
||||||
.migrate_account(async_std::path::PathBuf::from(dbfile))
|
.migrate_account(async_std::path::PathBuf::from(dbfile))
|
||||||
.await
|
.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]
|
#[no_mangle]
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use anyhow::{ensure, Context as _, Result};
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::context::Context;
|
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.
|
/// Account manager, that can handle multiple accounts in a single place.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -23,12 +23,8 @@ pub struct Accounts {
|
|||||||
accounts: BTreeMap<u32, Context>,
|
accounts: BTreeMap<u32, Context>,
|
||||||
emitter: EventEmitter,
|
emitter: EventEmitter,
|
||||||
|
|
||||||
/// Sender side of the fake event channel.
|
/// Event channel to emit account manager errors.
|
||||||
///
|
events: Events,
|
||||||
/// 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>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Accounts {
|
impl Accounts {
|
||||||
@@ -65,9 +61,9 @@ impl Accounts {
|
|||||||
|
|
||||||
let emitter = EventEmitter::new();
|
let emitter = EventEmitter::new();
|
||||||
|
|
||||||
// Fake event stream to prevent event emitter from closing.
|
let events = Events::default();
|
||||||
let (fake_sender, fake_receiver) = channel::bounded(1);
|
|
||||||
emitter.sender.send(fake_receiver).await?;
|
emitter.sender.send(events.get_emitter()).await?;
|
||||||
|
|
||||||
for account in accounts.values() {
|
for account in accounts.values() {
|
||||||
emitter.add_account(account).await?;
|
emitter.add_account(account).await?;
|
||||||
@@ -78,7 +74,7 @@ impl Accounts {
|
|||||||
config,
|
config,
|
||||||
accounts,
|
accounts,
|
||||||
emitter,
|
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.
|
/// Returns unified event emitter.
|
||||||
pub async fn get_event_emitter(&self) -> EventEmitter {
|
pub async fn get_event_emitter(&self) -> EventEmitter {
|
||||||
self.emitter.clone()
|
self.emitter.clone()
|
||||||
@@ -272,13 +273,13 @@ impl Accounts {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct EventEmitter {
|
pub struct EventEmitter {
|
||||||
/// Aggregate stream of events from all accounts.
|
/// 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 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 for the channel where new account emitters will be pushed.
|
||||||
receiver: Receiver<Receiver<crate::events::Event>>,
|
receiver: Receiver<crate::events::EventEmitter>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter {
|
impl EventEmitter {
|
||||||
@@ -311,9 +312,7 @@ impl EventEmitter {
|
|||||||
|
|
||||||
/// Add event emitter of a new account to the aggregate event emitter.
|
/// Add event emitter of a new account to the aggregate event emitter.
|
||||||
pub async fn add_account(&self, context: &Context) -> Result<()> {
|
pub async fn add_account(&self, context: &Context) -> Result<()> {
|
||||||
self.sender
|
self.sender.send(context.get_event_emitter()).await?;
|
||||||
.send(context.get_event_emitter().into_inner())
|
|
||||||
.await?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,10 +62,6 @@ impl Events {
|
|||||||
pub struct EventEmitter(Receiver<Event>);
|
pub struct EventEmitter(Receiver<Event>);
|
||||||
|
|
||||||
impl EventEmitter {
|
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.
|
/// Blocking recv of an event. Return `None` if the `Sender` has been droped.
|
||||||
pub fn recv_sync(&self) -> Option<Event> {
|
pub fn recv_sync(&self) -> Option<Event> {
|
||||||
async_std::task::block_on(self.recv())
|
async_std::task::block_on(self.recv())
|
||||||
|
|||||||
Reference in New Issue
Block a user