Make initiate_key_transfer() non-blocking

This commit is contained in:
link2xt
2022-08-14 21:13:06 +00:00
parent 56cd875fbd
commit c75bc66560
4 changed files with 14 additions and 37 deletions

View File

@@ -43,6 +43,9 @@
- jsonrpc: add `last_seen` property to `Contact` #3590
- breaking! jsonrpc: replace `Message.quoted_text` and `Message.quoted_message_id` with `Message.quote` #3590
- add separate stock strings for actions done by contacts to make them easier to translate #3518
- `dc_initiate_key_transfer()` is non-blocking now. #3553
UIs don't need to display a button to cancel sending Autocrypt Setup Message with
`dc_stop_ongoing_process()` anymore.
### Changes
- order contact lists by "last seen";

View File

@@ -2174,11 +2174,10 @@ char* dc_imex_has_backup (dc_context_t* context, const char*
* ~~~
*
* After that, this function should be called to send the Autocrypt Setup Message.
* The function creates the setup message and waits until it is really sent.
* As this may take a while, it is recommended to start the function in a separate thread;
* to interrupt it, you can use dc_stop_ongoing_process().
* The function creates the setup message and adds it to outgoing message queue.
* The message is sent asynchronously.
*
* After everything succeeded, the required setup code is returned in the following format:
* The required setup code is returned in the following format:
*
* ~~~
* 1234-1234-1234-1234-1234-1234-1234-1234-1234
@@ -2244,8 +2243,8 @@ int dc_continue_key_transfer (dc_context_t* context, uint32_t ms
* The ongoing process will return ASAP then, however, it may
* still take a moment.
*
* Typical ongoing processes are started by dc_configure(),
* dc_initiate_key_transfer() or dc_imex(). As there is always at most only
* Typical ongoing processes are started by dc_configure()
* or dc_imex(). As there is always at most only
* one onging process at the same time, there is no need to define _which_ process to exit.
*
* @memberof dc_context_t

View File

@@ -346,6 +346,7 @@ impl Context {
}
}
#[allow(unused)]
pub(crate) async fn shall_stop_ongoing(&self) -> bool {
match &*self.running_state.read().await {
RunningState::Running { .. } => false,

View File

@@ -134,19 +134,9 @@ pub async fn has_backup(_context: &Context, dir_name: &Path) -> Result<String> {
}
/// Initiates key transfer via Autocrypt Setup Message.
///
/// Returns setup code.
pub async fn initiate_key_transfer(context: &Context) -> Result<String> {
use futures::future::FutureExt;
let cancel = context.alloc_ongoing().await?;
let res = do_initiate_key_transfer(context)
.race(cancel.recv().map(|_| Err(format_err!("canceled"))))
.await;
context.free_ongoing().await;
res
}
async fn do_initiate_key_transfer(context: &Context) -> Result<String> {
let setup_code = create_setup_code(context);
/* this may require a keypair to be created. this may take a second ... */
let setup_file_content = render_setup_file(context, &setup_code).await?;
@@ -171,17 +161,7 @@ async fn do_initiate_key_transfer(context: &Context) -> Result<String> {
msg.force_plaintext();
msg.param.set_int(Param::SkipAutocrypt, 1);
let msg_id = chat::send_msg(context, chat_id, &mut msg).await?;
info!(context, "Wait for setup message being sent ...",);
while !context.shall_stop_ongoing().await {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
if let Ok(msg) = Message::load_from_db(context, msg_id).await {
if msg.is_sent() {
info!(context, "... setup message sent.",);
break;
}
}
}
chat::send_msg(context, chat_id, &mut msg).await?;
// no maybe_add_bcc_self_device_msg() here.
// the ui shows the dialog with the setup code on this device,
// it would be too much noise to have two things popping up at the same time.
@@ -980,16 +960,10 @@ mod tests {
async fn test_key_transfer() -> Result<()> {
let alice = TestContext::new_alice().await;
let alice_clone = alice.clone();
let key_transfer_task = tokio::task::spawn(async move {
let ctx = alice_clone;
initiate_key_transfer(&ctx).await
});
let setup_code = initiate_key_transfer(&alice).await?;
// Wait for the message to be added to the queue.
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
// Get Autocrypt Setup Message.
let sent = alice.pop_sent_msg().await;
let setup_code = key_transfer_task.await??;
// Alice sets up a second device.
let alice2 = TestContext::new().await;