mirror of
https://github.com/chatmail/core.git
synced 2026-05-03 05:16:28 +03:00
feat: add config option to enable iroh (#5607)
Co-authored-by: link2xt <link2xt@testrun.org>
This commit is contained in:
@@ -523,6 +523,9 @@ char* dc_get_blobdir (const dc_context_t* context);
|
|||||||
* e.g. `ui.desktop.foo`, `ui.desktop.linux.bar`, `ui.android.foo`, `ui.dc40.bar`, `ui.bot.simplebot.baz`.
|
* e.g. `ui.desktop.foo`, `ui.desktop.linux.bar`, `ui.android.foo`, `ui.dc40.bar`, `ui.bot.simplebot.baz`.
|
||||||
* These keys go to backups and allow easy per-account settings when using @ref dc_accounts_t,
|
* These keys go to backups and allow easy per-account settings when using @ref dc_accounts_t,
|
||||||
* however, are not handled by the core otherwise.
|
* however, are not handled by the core otherwise.
|
||||||
|
* - `webxdc_realtime_enabled` = Whether the realtime APIs should be enabled.
|
||||||
|
* 0 = WebXDC realtime API is disabled and behaves as noop (default).
|
||||||
|
* 1 = WebXDC realtime API is enabled.
|
||||||
*
|
*
|
||||||
* If you want to retrieve a value, use dc_get_config().
|
* If you want to retrieve a value, use dc_get_config().
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ def log(msg):
|
|||||||
|
|
||||||
|
|
||||||
def setup_realtime_webxdc(ac1, ac2, path_to_webxdc):
|
def setup_realtime_webxdc(ac1, ac2, path_to_webxdc):
|
||||||
|
assert ac1.get_config("webxdc_realtime_enabled") == "1"
|
||||||
|
assert ac2.get_config("webxdc_realtime_enabled") == "1"
|
||||||
ac1_ac2_chat = ac1.create_chat(ac2)
|
ac1_ac2_chat = ac1.create_chat(ac2)
|
||||||
ac2.create_chat(ac1)
|
ac2.create_chat(ac1)
|
||||||
|
|
||||||
@@ -75,6 +77,8 @@ def wait_receive_realtime_data(msg_data_list):
|
|||||||
def test_realtime_sequentially(acfactory, path_to_webxdc):
|
def test_realtime_sequentially(acfactory, path_to_webxdc):
|
||||||
"""Test two peers trying to establish connection sequentially."""
|
"""Test two peers trying to establish connection sequentially."""
|
||||||
ac1, ac2 = acfactory.get_online_accounts(2)
|
ac1, ac2 = acfactory.get_online_accounts(2)
|
||||||
|
ac1.set_config("webxdc_realtime_enabled", "1")
|
||||||
|
ac2.set_config("webxdc_realtime_enabled", "1")
|
||||||
ac1.create_chat(ac2)
|
ac1.create_chat(ac2)
|
||||||
ac2.create_chat(ac1)
|
ac2.create_chat(ac1)
|
||||||
|
|
||||||
@@ -115,6 +119,8 @@ def test_realtime_sequentially(acfactory, path_to_webxdc):
|
|||||||
def test_realtime_simultaneously(acfactory, path_to_webxdc):
|
def test_realtime_simultaneously(acfactory, path_to_webxdc):
|
||||||
"""Test two peers trying to establish connection simultaneously."""
|
"""Test two peers trying to establish connection simultaneously."""
|
||||||
ac1, ac2 = acfactory.get_online_accounts(2)
|
ac1, ac2 = acfactory.get_online_accounts(2)
|
||||||
|
ac1.set_config("webxdc_realtime_enabled", "1")
|
||||||
|
ac2.set_config("webxdc_realtime_enabled", "1")
|
||||||
|
|
||||||
ac1_webxdc_msg, ac2_webxdc_msg = setup_realtime_webxdc(ac1, ac2, path_to_webxdc)
|
ac1_webxdc_msg, ac2_webxdc_msg = setup_realtime_webxdc(ac1, ac2, path_to_webxdc)
|
||||||
|
|
||||||
@@ -125,6 +131,8 @@ def test_realtime_simultaneously(acfactory, path_to_webxdc):
|
|||||||
def test_two_parallel_realtime_simultaneously(acfactory, path_to_webxdc):
|
def test_two_parallel_realtime_simultaneously(acfactory, path_to_webxdc):
|
||||||
"""Test two peers trying to establish connection simultaneously."""
|
"""Test two peers trying to establish connection simultaneously."""
|
||||||
ac1, ac2 = acfactory.get_online_accounts(2)
|
ac1, ac2 = acfactory.get_online_accounts(2)
|
||||||
|
ac1.set_config("webxdc_realtime_enabled", "1")
|
||||||
|
ac2.set_config("webxdc_realtime_enabled", "1")
|
||||||
|
|
||||||
ac1_webxdc_msg, ac2_webxdc_msg = setup_realtime_webxdc(ac1, ac2, path_to_webxdc)
|
ac1_webxdc_msg, ac2_webxdc_msg = setup_realtime_webxdc(ac1, ac2, path_to_webxdc)
|
||||||
ac1_webxdc_msg2, ac2_webxdc_msg2 = setup_realtime_webxdc(ac1, ac2, path_to_webxdc)
|
ac1_webxdc_msg2, ac2_webxdc_msg2 = setup_realtime_webxdc(ac1, ac2, path_to_webxdc)
|
||||||
@@ -141,6 +149,8 @@ def test_two_parallel_realtime_simultaneously(acfactory, path_to_webxdc):
|
|||||||
def test_no_duplicate_messages(acfactory, path_to_webxdc):
|
def test_no_duplicate_messages(acfactory, path_to_webxdc):
|
||||||
"""Test that messages are received only once."""
|
"""Test that messages are received only once."""
|
||||||
ac1, ac2 = acfactory.get_online_accounts(2)
|
ac1, ac2 = acfactory.get_online_accounts(2)
|
||||||
|
ac1.set_config("webxdc_realtime_enabled", "1")
|
||||||
|
ac2.set_config("webxdc_realtime_enabled", "1")
|
||||||
|
|
||||||
ac1_ac2_chat = ac1.create_chat(ac2)
|
ac1_ac2_chat = ac1.create_chat(ac2)
|
||||||
|
|
||||||
|
|||||||
@@ -363,8 +363,8 @@ pub enum Config {
|
|||||||
/// MsgId of webxdc map integration.
|
/// MsgId of webxdc map integration.
|
||||||
WebxdcIntegration,
|
WebxdcIntegration,
|
||||||
|
|
||||||
/// Iroh secret key.
|
/// Enable webxdc realtime features.
|
||||||
IrohSecretKey,
|
WebxdcRealtimeEnabled,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
|
|||||||
@@ -967,6 +967,12 @@ impl Context {
|
|||||||
.await?
|
.await?
|
||||||
.to_string(),
|
.to_string(),
|
||||||
);
|
);
|
||||||
|
res.insert(
|
||||||
|
"webxdc_realtime_enabled",
|
||||||
|
self.get_config_bool(Config::WebxdcRealtimeEnabled)
|
||||||
|
.await?
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
let elapsed = time_elapsed(&self.creation_time);
|
let elapsed = time_elapsed(&self.creation_time);
|
||||||
res.insert("uptime", duration_to_str(elapsed));
|
res.insert("uptime", duration_to_str(elapsed));
|
||||||
@@ -1673,7 +1679,6 @@ mod tests {
|
|||||||
"socks5_password",
|
"socks5_password",
|
||||||
"key_id",
|
"key_id",
|
||||||
"webxdc_integration",
|
"webxdc_integration",
|
||||||
"iroh_secret_key",
|
|
||||||
];
|
];
|
||||||
let t = TestContext::new().await;
|
let t = TestContext::new().await;
|
||||||
let info = t.get_info().await.unwrap();
|
let info = t.get_info().await.unwrap();
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ use tokio::task::JoinHandle;
|
|||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::chat::send_msg;
|
use crate::chat::send_msg;
|
||||||
|
use crate::config::Config;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::headerdef::HeaderDef;
|
use crate::headerdef::HeaderDef;
|
||||||
use crate::message::{Message, MsgId, Viewtype};
|
use crate::message::{Message, MsgId, Viewtype};
|
||||||
@@ -338,6 +339,10 @@ pub async fn send_webxdc_realtime_advertisement(
|
|||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
msg_id: MsgId,
|
msg_id: MsgId,
|
||||||
) -> Result<Option<JoinTopicFut>> {
|
) -> Result<Option<JoinTopicFut>> {
|
||||||
|
if !ctx.get_config_bool(Config::WebxdcRealtimeEnabled).await? {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
let iroh = ctx.get_or_try_init_peer_channel().await?;
|
let iroh = ctx.get_or_try_init_peer_channel().await?;
|
||||||
let conn = iroh.join_and_subscribe_gossip(ctx, msg_id).await?;
|
let conn = iroh.join_and_subscribe_gossip(ctx, msg_id).await?;
|
||||||
|
|
||||||
@@ -351,8 +356,12 @@ pub async fn send_webxdc_realtime_advertisement(
|
|||||||
Ok(conn)
|
Ok(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send realtime data to the gossip swarm.
|
/// Send realtime data to other peers using iroh.
|
||||||
pub async fn send_webxdc_realtime_data(ctx: &Context, msg_id: MsgId, data: Vec<u8>) -> Result<()> {
|
pub async fn send_webxdc_realtime_data(ctx: &Context, msg_id: MsgId, data: Vec<u8>) -> Result<()> {
|
||||||
|
if !ctx.get_config_bool(Config::WebxdcRealtimeEnabled).await? {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
let iroh = ctx.get_or_try_init_peer_channel().await?;
|
let iroh = ctx.get_or_try_init_peer_channel().await?;
|
||||||
iroh.send_webxdc_realtime_data(ctx, msg_id, data).await?;
|
iroh.send_webxdc_realtime_data(ctx, msg_id, data).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -360,6 +369,10 @@ pub async fn send_webxdc_realtime_data(ctx: &Context, msg_id: MsgId, data: Vec<u
|
|||||||
|
|
||||||
/// Leave the gossip of the webxdc with given [MsgId].
|
/// Leave the gossip of the webxdc with given [MsgId].
|
||||||
pub async fn leave_webxdc_realtime(ctx: &Context, msg_id: MsgId) -> Result<()> {
|
pub async fn leave_webxdc_realtime(ctx: &Context, msg_id: MsgId) -> Result<()> {
|
||||||
|
if !ctx.get_config_bool(Config::WebxdcRealtimeEnabled).await? {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
let iroh = ctx.get_or_try_init_peer_channel().await?;
|
let iroh = ctx.get_or_try_init_peer_channel().await?;
|
||||||
iroh.leave_realtime(get_iroh_topic_for_msg(ctx, msg_id).await?)
|
iroh.leave_realtime(get_iroh_topic_for_msg(ctx, msg_id).await?)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -465,6 +478,17 @@ mod tests {
|
|||||||
let alice = &mut tcm.alice().await;
|
let alice = &mut tcm.alice().await;
|
||||||
let bob = &mut tcm.bob().await;
|
let bob = &mut tcm.bob().await;
|
||||||
|
|
||||||
|
bob.ctx
|
||||||
|
.set_config_bool(Config::WebxdcRealtimeEnabled, true)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
alice
|
||||||
|
.ctx
|
||||||
|
.set_config_bool(Config::WebxdcRealtimeEnabled, true)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// Alice sends webxdc to bob
|
// Alice sends webxdc to bob
|
||||||
let alice_chat = alice.create_chat(bob).await;
|
let alice_chat = alice.create_chat(bob).await;
|
||||||
let mut instance = Message::new(Viewtype::File);
|
let mut instance = Message::new(Viewtype::File);
|
||||||
@@ -596,6 +620,21 @@ mod tests {
|
|||||||
let alice = &mut tcm.alice().await;
|
let alice = &mut tcm.alice().await;
|
||||||
let bob = &mut tcm.bob().await;
|
let bob = &mut tcm.bob().await;
|
||||||
|
|
||||||
|
bob.ctx
|
||||||
|
.set_config_bool(Config::WebxdcRealtimeEnabled, true)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
alice
|
||||||
|
.ctx
|
||||||
|
.set_config_bool(Config::WebxdcRealtimeEnabled, true)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert!(alice
|
||||||
|
.get_config_bool(Config::WebxdcRealtimeEnabled)
|
||||||
|
.await
|
||||||
|
.unwrap());
|
||||||
// Alice sends webxdc to bob
|
// Alice sends webxdc to bob
|
||||||
let alice_chat = alice.create_chat(bob).await;
|
let alice_chat = alice.create_chat(bob).await;
|
||||||
let mut instance = Message::new(Viewtype::File);
|
let mut instance = Message::new(Viewtype::File);
|
||||||
@@ -731,6 +770,17 @@ mod tests {
|
|||||||
let alice = &mut tcm.alice().await;
|
let alice = &mut tcm.alice().await;
|
||||||
let bob = &mut tcm.bob().await;
|
let bob = &mut tcm.bob().await;
|
||||||
|
|
||||||
|
bob.ctx
|
||||||
|
.set_config_bool(Config::WebxdcRealtimeEnabled, true)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
alice
|
||||||
|
.ctx
|
||||||
|
.set_config_bool(Config::WebxdcRealtimeEnabled, true)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// Alice sends webxdc to bob
|
// Alice sends webxdc to bob
|
||||||
let alice_chat = alice.create_chat(bob).await;
|
let alice_chat = alice.create_chat(bob).await;
|
||||||
let mut instance = Message::new(Viewtype::File);
|
let mut instance = Message::new(Viewtype::File);
|
||||||
@@ -793,4 +843,29 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
|
async fn test_peer_channels_disabled() {
|
||||||
|
let mut tcm = TestContextManager::new();
|
||||||
|
let alice = &mut tcm.alice().await;
|
||||||
|
|
||||||
|
// creates iroh endpoint as side effect
|
||||||
|
send_webxdc_realtime_advertisement(alice, MsgId::new(1))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert!(alice.ctx.iroh.get().is_none());
|
||||||
|
|
||||||
|
// creates iroh endpoint as side effect
|
||||||
|
send_webxdc_realtime_data(alice, MsgId::new(1), vec![])
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert!(alice.ctx.iroh.get().is_none());
|
||||||
|
|
||||||
|
// creates iroh endpoint as side effect
|
||||||
|
leave_webxdc_realtime(alice, MsgId::new(1)).await.unwrap();
|
||||||
|
|
||||||
|
assert!(alice.ctx.iroh.get().is_none())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user