|
|
|
@ -1,5 +1,6 @@ |
|
|
|
use std::path::PathBuf; |
|
|
|
use std::path::PathBuf; |
|
|
|
use std::sync::Arc; |
|
|
|
use std::sync::Arc; |
|
|
|
|
|
|
|
use std::time::{SystemTime, UNIX_EPOCH}; |
|
|
|
use tdn::types::{ |
|
|
|
use tdn::types::{ |
|
|
|
group::GroupId, |
|
|
|
group::GroupId, |
|
|
|
message::{RecvType, SendType}, |
|
|
|
message::{RecvType, SendType}, |
|
|
|
@ -8,7 +9,7 @@ use tdn::types::{ |
|
|
|
use tokio::sync::RwLock; |
|
|
|
use tokio::sync::RwLock; |
|
|
|
|
|
|
|
|
|
|
|
use group_chat_types::{ |
|
|
|
use group_chat_types::{ |
|
|
|
ConnectProof, Event, JoinProof, LayerConnect, LayerEvent, LayerResult, PackedEvent, |
|
|
|
ConnectProof, Event, GroupType, JoinProof, LayerConnect, LayerEvent, LayerResult, PackedEvent, |
|
|
|
}; |
|
|
|
}; |
|
|
|
use tdn_did::Proof; |
|
|
|
use tdn_did::Proof; |
|
|
|
use tdn_storage::local::DStorage; |
|
|
|
use tdn_storage::local::DStorage; |
|
|
|
@ -17,23 +18,82 @@ use crate::apps::chat::Friend; |
|
|
|
use crate::layer::{Layer, Online}; |
|
|
|
use crate::layer::{Layer, Online}; |
|
|
|
use crate::rpc::{session_connect, session_create, session_last, session_lost, session_suspend}; |
|
|
|
use crate::rpc::{session_connect, session_create, session_last, session_lost, session_suspend}; |
|
|
|
use crate::session::{connect_session, Session, SessionType}; |
|
|
|
use crate::session::{connect_session, Session, SessionType}; |
|
|
|
use crate::storage::{chat_db, delete_avatar, group_chat_db, session_db, write_avatar_sync}; |
|
|
|
use crate::storage::{ |
|
|
|
|
|
|
|
chat_db, delete_avatar, group_chat_db, read_avatar, session_db, write_avatar, write_avatar_sync, |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
use super::models::{from_network_message, GroupChat, Member, Request}; |
|
|
|
use super::models::{from_network_message, GroupChat, Member, Request}; |
|
|
|
use super::{add_layer, rpc}; |
|
|
|
use super::{add_layer, add_server_layer, rpc}; |
|
|
|
|
|
|
|
|
|
|
|
pub(crate) async fn handle( |
|
|
|
pub(crate) async fn handle( |
|
|
|
layer: &Arc<RwLock<Layer>>, |
|
|
|
layer: &Arc<RwLock<Layer>>, |
|
|
|
mgid: GroupId, |
|
|
|
fgid: GroupId, // when as client, `fgid` is GROUP_ID
|
|
|
|
|
|
|
|
mgid: GroupId, // when as server, `mgid` is GROUP_ID
|
|
|
|
|
|
|
|
is_server: bool, |
|
|
|
msg: RecvType, |
|
|
|
msg: RecvType, |
|
|
|
) -> Result<HandleResult> { |
|
|
|
) -> Result<HandleResult> { |
|
|
|
let mut results = HandleResult::new(); |
|
|
|
let mut results = HandleResult::new(); |
|
|
|
|
|
|
|
|
|
|
|
match msg { |
|
|
|
match msg { |
|
|
|
RecvType::Connect(..) => {} // Never to here.
|
|
|
|
RecvType::Connect(addr, data) => { |
|
|
|
RecvType::Leave(..) => {} // Never to here. handled in chat.
|
|
|
|
// only server handle it.
|
|
|
|
|
|
|
|
if !is_server { |
|
|
|
|
|
|
|
let s = SendType::Result(0, addr, false, false, vec![]); |
|
|
|
|
|
|
|
add_server_layer(&mut results, fgid, s); |
|
|
|
|
|
|
|
return Ok(results); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let LayerConnect(gcd, connect) = bincode::deserialize(&data) |
|
|
|
|
|
|
|
.map_err(|_e| new_io_error("deserialize group chat connect failure"))?; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let (ogid, height, id) = layer.read().await.running(&gcd)?.owner_height_id(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
match connect { |
|
|
|
|
|
|
|
ConnectProof::Common(_proof) => { |
|
|
|
|
|
|
|
// check is member.
|
|
|
|
|
|
|
|
let db = group_chat_db(&layer.read().await.base, &ogid)?; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if let Ok(mid) = Member::get_id(&db, &id, &fgid) { |
|
|
|
|
|
|
|
let res = LayerResult(gcd, height); |
|
|
|
|
|
|
|
let data = bincode::serialize(&res).unwrap_or(vec![]); |
|
|
|
|
|
|
|
let s = SendType::Result(0, addr, true, false, data); |
|
|
|
|
|
|
|
add_server_layer(&mut results, fgid, s); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
layer.write().await.running_mut(&gcd)?.check_add_online( |
|
|
|
|
|
|
|
mgid, |
|
|
|
|
|
|
|
Online::Direct(addr), |
|
|
|
|
|
|
|
id, |
|
|
|
|
|
|
|
mid, |
|
|
|
|
|
|
|
)?; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let _ = Member::addr_update(&db, &id, &fgid, &addr); |
|
|
|
|
|
|
|
results.rpcs.push(rpc::member_online(mgid, id, fgid, addr)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let new_data = |
|
|
|
|
|
|
|
bincode::serialize(&LayerEvent::MemberOnline(gcd, fgid, addr)) |
|
|
|
|
|
|
|
.map_err(|_| new_io_error("serialize event error."))?; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (mid, maddr) in layer.read().await.running(&gcd)?.onlines() { |
|
|
|
|
|
|
|
let s = SendType::Event(0, *maddr, new_data.clone()); |
|
|
|
|
|
|
|
add_server_layer(&mut results, *mid, s); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
let s = SendType::Result(0, addr, false, false, vec![]); |
|
|
|
|
|
|
|
add_server_layer(&mut results, fgid, s); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ConnectProof::Zkp(_proof) => { |
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
RecvType::Leave(_addr) => { |
|
|
|
|
|
|
|
// only server handle it.
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
|
|
|
|
} |
|
|
|
RecvType::Result(addr, is_ok, data) => { |
|
|
|
RecvType::Result(addr, is_ok, data) => { |
|
|
|
if is_ok { |
|
|
|
// only client handle it.
|
|
|
|
|
|
|
|
if !is_server && is_ok { |
|
|
|
let mut layer_lock = layer.write().await; |
|
|
|
let mut layer_lock = layer.write().await; |
|
|
|
handle_connect(mgid, addr, data, &mut layer_lock, &mut results)?; |
|
|
|
handle_connect(mgid, addr, data, &mut layer_lock, &mut results)?; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
@ -42,6 +102,12 @@ pub(crate) async fn handle( |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
RecvType::ResultConnect(addr, data) => { |
|
|
|
RecvType::ResultConnect(addr, data) => { |
|
|
|
|
|
|
|
// only client handle it.
|
|
|
|
|
|
|
|
if is_server { |
|
|
|
|
|
|
|
let msg = SendType::Result(0, addr, false, false, vec![]); |
|
|
|
|
|
|
|
add_layer(&mut results, mgid, msg); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
let mut layer_lock = layer.write().await; |
|
|
|
let mut layer_lock = layer.write().await; |
|
|
|
if handle_connect(mgid, addr, data, &mut layer_lock, &mut results)? { |
|
|
|
if handle_connect(mgid, addr, data, &mut layer_lock, &mut results)? { |
|
|
|
let msg = SendType::Result(0, addr, true, false, vec![]); |
|
|
|
let msg = SendType::Result(0, addr, true, false, vec![]); |
|
|
|
@ -49,9 +115,10 @@ pub(crate) async fn handle( |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
RecvType::Event(addr, bytes) => { |
|
|
|
RecvType::Event(addr, bytes) => { |
|
|
|
|
|
|
|
// server & client handle it.
|
|
|
|
let event: LayerEvent = |
|
|
|
let event: LayerEvent = |
|
|
|
bincode::deserialize(&bytes).map_err(|_| new_io_error("serialize event error."))?; |
|
|
|
bincode::deserialize(&bytes).map_err(|_| new_io_error("serialize event error."))?; |
|
|
|
handle_event(mgid, addr, event, layer, &mut results).await?; |
|
|
|
handle_event(fgid, mgid, is_server, addr, event, layer, &mut results).await?; |
|
|
|
} |
|
|
|
} |
|
|
|
RecvType::Stream(_uid, _stream, _bytes) => { |
|
|
|
RecvType::Stream(_uid, _stream, _bytes) => { |
|
|
|
// TODO stream
|
|
|
|
// TODO stream
|
|
|
|
@ -113,7 +180,9 @@ fn handle_connect( |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async fn handle_event( |
|
|
|
async fn handle_event( |
|
|
|
mgid: GroupId, |
|
|
|
fgid: GroupId, // server use fgid is remote account.
|
|
|
|
|
|
|
|
mgid: GroupId, // client user mgid is my account.
|
|
|
|
|
|
|
|
is_server: bool, |
|
|
|
addr: PeerAddr, |
|
|
|
addr: PeerAddr, |
|
|
|
event: LayerEvent, |
|
|
|
event: LayerEvent, |
|
|
|
layer: &Arc<RwLock<Layer>>, |
|
|
|
layer: &Arc<RwLock<Layer>>, |
|
|
|
@ -122,11 +191,31 @@ async fn handle_event( |
|
|
|
println!("Got event......."); |
|
|
|
println!("Got event......."); |
|
|
|
match event { |
|
|
|
match event { |
|
|
|
LayerEvent::Offline(gcd) => { |
|
|
|
LayerEvent::Offline(gcd) => { |
|
|
|
let mut layer_lock = layer.write().await; |
|
|
|
if is_server { |
|
|
|
let (sid, _gid) = layer_lock.get_running_remote_id(&mgid, &gcd)?; |
|
|
|
// 1. check member online.
|
|
|
|
layer_lock.running_mut(&mgid)?.check_offline(&gcd, &addr); |
|
|
|
if layer.write().await.remove_online(&gcd, &fgid).is_none() { |
|
|
|
drop(layer_lock); |
|
|
|
return Ok(()); |
|
|
|
results.rpcs.push(session_lost(mgid, &sid)); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2. offline this member.
|
|
|
|
|
|
|
|
let (ogid, _, id) = layer.read().await.running(&gcd)?.owner_height_id(); |
|
|
|
|
|
|
|
results.rpcs.push(rpc::member_offline(ogid, id, fgid)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3. broadcast offline event.
|
|
|
|
|
|
|
|
let new_data = bincode::serialize(&LayerEvent::MemberOffline(gcd, fgid)) |
|
|
|
|
|
|
|
.map_err(|_| new_io_error("serialize event error."))?; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (mid, maddr) in layer.read().await.running(&gcd)?.onlines() { |
|
|
|
|
|
|
|
let s = SendType::Event(0, *maddr, new_data.clone()); |
|
|
|
|
|
|
|
add_layer(results, *mid, s); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
let mut layer_lock = layer.write().await; |
|
|
|
|
|
|
|
let (sid, _gid) = layer_lock.get_running_remote_id(&mgid, &gcd)?; |
|
|
|
|
|
|
|
layer_lock.running_mut(&mgid)?.check_offline(&gcd, &addr); |
|
|
|
|
|
|
|
drop(layer_lock); |
|
|
|
|
|
|
|
results.rpcs.push(session_lost(mgid, &sid)); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
LayerEvent::Suspend(gcd) => { |
|
|
|
LayerEvent::Suspend(gcd) => { |
|
|
|
let mut layer_lock = layer.write().await; |
|
|
|
let mut layer_lock = layer.write().await; |
|
|
|
@ -330,11 +419,117 @@ async fn handle_event( |
|
|
|
let id = Request::over_rid(&db, &gcd, &rid, ok)?; |
|
|
|
let id = Request::over_rid(&db, &gcd, &rid, ok)?; |
|
|
|
results.rpcs.push(rpc::request_handle(mgid, id, ok, false)); |
|
|
|
results.rpcs.push(rpc::request_handle(mgid, id, ok, false)); |
|
|
|
} |
|
|
|
} |
|
|
|
LayerEvent::MemberOnlineSync(..) => {} // nerver here.
|
|
|
|
LayerEvent::MemberOnlineSync(..) => { |
|
|
|
LayerEvent::Request(..) => {} // nerver here.
|
|
|
|
// TODO
|
|
|
|
LayerEvent::Check => {} // nerver here.
|
|
|
|
} |
|
|
|
LayerEvent::Create(..) => {} // nerver here.
|
|
|
|
LayerEvent::Request(gcd, join_proof) => { |
|
|
|
LayerEvent::SyncReq(..) => {} // Nerver here.
|
|
|
|
let (ogid, height, id) = layer.read().await.running(&gcd)?.owner_height_id(); |
|
|
|
|
|
|
|
let base = layer.read().await.base.clone(); |
|
|
|
|
|
|
|
let db = group_chat_db(&base, &ogid)?; |
|
|
|
|
|
|
|
let group = GroupChat::get_id(&db, &id)?.ok_or(new_io_error("missing group"))?; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1. check account is online, if not online, nothing.
|
|
|
|
|
|
|
|
match join_proof { |
|
|
|
|
|
|
|
JoinProof::Open(mname, mavatar) => { |
|
|
|
|
|
|
|
// check is member.
|
|
|
|
|
|
|
|
if let Ok(mid) = Member::get_id(&db, &id, &fgid) { |
|
|
|
|
|
|
|
let gavatar = read_avatar(&base, &ogid, &gcd).await?; |
|
|
|
|
|
|
|
let group_info = group.to_group_info("".to_owned(), gavatar, vec![]); |
|
|
|
|
|
|
|
let res = LayerEvent::Agree(gcd, group_info); |
|
|
|
|
|
|
|
let d = bincode::serialize(&res).unwrap_or(vec![]); |
|
|
|
|
|
|
|
let s = SendType::Event(0, addr, d); |
|
|
|
|
|
|
|
add_server_layer(results, fgid, s); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return Ok(()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if group.g_type == GroupType::Open { |
|
|
|
|
|
|
|
let start = SystemTime::now(); |
|
|
|
|
|
|
|
let datetime = start |
|
|
|
|
|
|
|
.duration_since(UNIX_EPOCH) |
|
|
|
|
|
|
|
.map(|s| s.as_secs()) |
|
|
|
|
|
|
|
.unwrap_or(0) as i64; // safe for all life.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut m = Member::new(id, fgid, addr, mname, false, datetime); |
|
|
|
|
|
|
|
m.insert(&db)?; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// save avatar.
|
|
|
|
|
|
|
|
let _ = write_avatar(&base, &ogid, &fgid, &mavatar).await; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// add_height consensus.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// self.broadcast_join(&gcd, m, mavatar, results).await?;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// return join result.
|
|
|
|
|
|
|
|
let gavatar = read_avatar(&base, &ogid, &gcd).await?; |
|
|
|
|
|
|
|
let group_info = group.to_group_info("".to_owned(), gavatar, vec![]); |
|
|
|
|
|
|
|
let res = LayerEvent::Agree(gcd, group_info); |
|
|
|
|
|
|
|
let d = bincode::serialize(&res).unwrap_or(vec![]); |
|
|
|
|
|
|
|
let s = SendType::Event(0, addr, d); |
|
|
|
|
|
|
|
add_server_layer(results, fgid, s); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
// Self::reject(gcd, fmid, addr, false, results);
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
JoinProof::Invite(invite_gid, proof, mname, mavatar) => { |
|
|
|
|
|
|
|
// check is member.
|
|
|
|
|
|
|
|
if let Ok(mid) = Member::get_id(&db, &id, &fgid) { |
|
|
|
|
|
|
|
let gavatar = read_avatar(&base, &ogid, &gcd).await?; |
|
|
|
|
|
|
|
let group_info = group.to_group_info("".to_owned(), gavatar, vec![]); |
|
|
|
|
|
|
|
let res = LayerEvent::Agree(gcd, group_info); |
|
|
|
|
|
|
|
let d = bincode::serialize(&res).unwrap_or(vec![]); |
|
|
|
|
|
|
|
let s = SendType::Event(0, addr, d); |
|
|
|
|
|
|
|
add_server_layer(results, fgid, s); |
|
|
|
|
|
|
|
return Ok(()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO check if request had or is blocked by manager.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check if inviter is member.
|
|
|
|
|
|
|
|
if Member::get_id(&db, &id, &invite_gid).is_err() { |
|
|
|
|
|
|
|
//Self::reject(gcd, fmid, addr, true, results);
|
|
|
|
|
|
|
|
return Ok(()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO check proof.
|
|
|
|
|
|
|
|
// proof.verify(&invite_gid, &addr, &layer.addr)?;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if group.is_need_agree {
|
|
|
|
|
|
|
|
// if !Member::is_manager(fid, &invite_gid).await? {
|
|
|
|
|
|
|
|
// let mut request = Request::new();
|
|
|
|
|
|
|
|
// request.insert().await?;
|
|
|
|
|
|
|
|
// self.broadcast_request(
|
|
|
|
|
|
|
|
// &gcd,
|
|
|
|
|
|
|
|
// request,
|
|
|
|
|
|
|
|
// JoinProof::Invite(invite_gid, proof, mname, mavatar),
|
|
|
|
|
|
|
|
// results,
|
|
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
// return Ok(());
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//let mut m = Member::new(*fid, fmid, addr, mname, false);
|
|
|
|
|
|
|
|
//m.insert().await?;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// save avatar.
|
|
|
|
|
|
|
|
//let _ = write_avatar(&self.base, &gcd, &m.m_id, &mavatar).await;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//self.add_member(&gcd, fmid, addr);
|
|
|
|
|
|
|
|
//self.broadcast_join(&gcd, m, mavatar, results).await?;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// return join result.
|
|
|
|
|
|
|
|
//self.agree(gcd, fmid, addr, group, results).await?;
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
JoinProof::Zkp(_proof) => { |
|
|
|
|
|
|
|
// TOOD zkp join.
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
LayerEvent::SyncReq(..) => { |
|
|
|
|
|
|
|
// TODO
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
LayerEvent::Check => {} // nerver here.
|
|
|
|
|
|
|
|
LayerEvent::Create(..) => {} // nerver here.
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
@ -363,6 +558,39 @@ fn sync_online(gcd: GroupId, addr: PeerAddr) -> SendType { |
|
|
|
SendType::Event(0, addr, data) |
|
|
|
SendType::Event(0, addr, data) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// fn broadcast_join(
|
|
|
|
|
|
|
|
// gcd: &GroupId,
|
|
|
|
|
|
|
|
// member: Member,
|
|
|
|
|
|
|
|
// avatar: Vec<u8>,
|
|
|
|
|
|
|
|
// results: &mut HandleResult,
|
|
|
|
|
|
|
|
// ) -> Result<()> {
|
|
|
|
|
|
|
|
// println!("start broadcast join...");
|
|
|
|
|
|
|
|
// let height = self
|
|
|
|
|
|
|
|
// .add_height(gcd, &member.id, ConsensusType::MemberJoin)
|
|
|
|
|
|
|
|
// .await?;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// let datetime = member.datetime;
|
|
|
|
|
|
|
|
// let event = Event::MemberJoin(
|
|
|
|
|
|
|
|
// member.m_id,
|
|
|
|
|
|
|
|
// member.m_addr,
|
|
|
|
|
|
|
|
// member.m_name,
|
|
|
|
|
|
|
|
// avatar,
|
|
|
|
|
|
|
|
// member.datetime,
|
|
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// let new_data = bincode::serialize(&LayerEvent::Sync(*gcd, height, event)).unwrap_or(vec![]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if let Some((members, _, _)) = self.groups.get(gcd) {
|
|
|
|
|
|
|
|
// for (mid, maddr, _) in members {
|
|
|
|
|
|
|
|
// let s = SendType::Event(0, *maddr, new_data.clone());
|
|
|
|
|
|
|
|
// add_layer(results, *mid, s);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// println!("over broadcast join...");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Ok(())
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
fn handle_sync( |
|
|
|
fn handle_sync( |
|
|
|
mgid: GroupId, |
|
|
|
mgid: GroupId, |
|
|
|
fid: i64, |
|
|
|
fid: i64, |
|
|
|
|