Add functions to add peers to a family in Ubisync
. Relates to #5
This commit is contained in:
parent
a8a8d2968b
commit
6581c3b9c6
5 changed files with 99 additions and 8 deletions
|
@ -160,6 +160,10 @@ impl CommHandle {
|
||||||
Ok(i2p_dest)
|
Ok(i2p_dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn own_peer_id(&self) -> anyhow::Result<PeerId> {
|
||||||
|
Ok(self.i2p_address()?.into())
|
||||||
|
}
|
||||||
|
|
||||||
fn read_connection(
|
fn read_connection(
|
||||||
wrapped_stream: Arc<RwLock<I2pStream>>,
|
wrapped_stream: Arc<RwLock<I2pStream>>,
|
||||||
state: Arc<CommState>,
|
state: Arc<CommState>,
|
||||||
|
|
|
@ -61,14 +61,19 @@ impl Ubisync {
|
||||||
|
|
||||||
pub fn add_peer(&self, p: impl TryInto<Peer, Error = anyhow::Error>) -> anyhow::Result<()> {
|
pub fn add_peer(&self, p: impl TryInto<Peer, Error = anyhow::Error>) -> anyhow::Result<()> {
|
||||||
match p.try_into() {
|
match p.try_into() {
|
||||||
Ok(peer) => self.state_handle.set_peer(peer),
|
Ok(peer) => self.state_handle.add_peer(peer),
|
||||||
Err(e) => bail!(e),
|
Err(e) => bail!(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_peer_from_id(&self, id: PeerId) -> anyhow::Result<()> {
|
pub fn add_peer_from_id(&self, id: PeerId) -> anyhow::Result<()> {
|
||||||
// TODO: resolve peer's name before setting
|
// TODO: resolve peer's name before setting
|
||||||
self.state_handle.set_peer(Peer::new(id, None))
|
self.state_handle.add_peer(Peer::new(id, None))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_family_member_from_id(&self, id: PeerId) -> anyhow::Result<()> {
|
||||||
|
self.add_peer_from_id(id.clone())?;
|
||||||
|
self.state_handle.add_family_member(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_apps(&self) -> Vec<App> {
|
pub fn get_apps(&self) -> Vec<App> {
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use anyhow::{anyhow, Error};
|
use anyhow::{anyhow, Error};
|
||||||
use bonsaidb::core::schema::{Collection, SerializedCollection};
|
use bonsaidb::core::{
|
||||||
|
connection::Connection,
|
||||||
|
document::Emit,
|
||||||
|
schema::{view::map::Mappings, Collection, MapReduce, SerializedCollection, View, ViewSchema},
|
||||||
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use ubisync_lib::types::{Family, FamilyId, PeerId};
|
use ubisync_lib::types::{Family, FamilyId, PeerId};
|
||||||
|
@ -9,7 +13,7 @@ use ubisync_lib::types::{Family, FamilyId, PeerId};
|
||||||
use crate::state::database::{as_key::AsKey, StateDB};
|
use crate::state::database::{as_key::AsKey, StateDB};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Collection, PartialEq, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Collection, PartialEq, Clone)]
|
||||||
#[collection(name = "peer-families", views = [])]
|
#[collection(name = "peer-families", views = [DbPeerFamilyByMemberId])]
|
||||||
pub(super) struct DbPeerFamily {
|
pub(super) struct DbPeerFamily {
|
||||||
#[natural_id]
|
#[natural_id]
|
||||||
pub(super) id: AsKey<FamilyId>,
|
pub(super) id: AsKey<FamilyId>,
|
||||||
|
@ -17,6 +21,33 @@ pub(super) struct DbPeerFamily {
|
||||||
pub(super) members: HashSet<PeerId>,
|
pub(super) members: HashSet<PeerId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, View, ViewSchema)]
|
||||||
|
#[view(collection = DbPeerFamily, key = AsKey<PeerId>, value = Option<FamilyId>, name = "by-member-id")]
|
||||||
|
pub(super) struct DbPeerFamilyByMemberId;
|
||||||
|
|
||||||
|
impl MapReduce for DbPeerFamilyByMemberId {
|
||||||
|
fn map<'doc>(
|
||||||
|
&self,
|
||||||
|
document: &'doc bonsaidb::core::document::BorrowedDocument<'_>,
|
||||||
|
) -> bonsaidb::core::schema::ViewMapResult<'doc, Self> {
|
||||||
|
let content = DbPeerFamily::document_contents(document)?;
|
||||||
|
Ok(content
|
||||||
|
.members
|
||||||
|
.iter()
|
||||||
|
.fold(Mappings::default(), |acc, member| {
|
||||||
|
acc.and(
|
||||||
|
document
|
||||||
|
.header
|
||||||
|
.emit_key_and_value(
|
||||||
|
AsKey::new(member.to_owned()),
|
||||||
|
Some((*content.id).clone()),
|
||||||
|
)
|
||||||
|
.unwrap_or(Mappings::none()),
|
||||||
|
)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<DbPeerFamily> for Family {
|
impl From<DbPeerFamily> for Family {
|
||||||
fn from(value: DbPeerFamily) -> Self {
|
fn from(value: DbPeerFamily) -> Self {
|
||||||
Family {
|
Family {
|
||||||
|
@ -75,6 +106,19 @@ impl StateDB {
|
||||||
.map(|doc_opt| doc_opt.map(|doc| doc.contents.into()))
|
.map(|doc_opt| doc_opt.map(|doc| doc.contents.into()))
|
||||||
.map_err(|e| anyhow!(e))
|
.map_err(|e| anyhow!(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_family_of_peer(&self, peer: PeerId) -> anyhow::Result<Option<FamilyId>> {
|
||||||
|
self.db
|
||||||
|
.view::<DbPeerFamilyByMemberId>()
|
||||||
|
.with_key(&AsKey::new(peer))
|
||||||
|
.query_with_collection_docs()
|
||||||
|
.map(|results| match results.mappings.len() {
|
||||||
|
0 => Ok(None),
|
||||||
|
1 => Ok(results.mappings.first().unwrap().value.clone()),
|
||||||
|
_ => Err(Error::msg("Peer appears to be member of multiple families")),
|
||||||
|
})?
|
||||||
|
.map_err(|e| anyhow!(e))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -141,4 +185,20 @@ mod tests {
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_family_of_peer() {
|
||||||
|
let db = StateDB::init(None);
|
||||||
|
let family_id = FamilyId::new();
|
||||||
|
let peer_id = PeerId::default();
|
||||||
|
|
||||||
|
db.add_peer_family(
|
||||||
|
family_id.clone(),
|
||||||
|
Some("My family name".to_string()),
|
||||||
|
vec![peer_id.clone()],
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(db.get_family_of_peer(peer_id).unwrap(), Some(family_id))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use ubisync_lib::{
|
||||||
api::events::AppEvent,
|
api::events::AppEvent,
|
||||||
messages::{Message, MessageContent},
|
messages::{Message, MessageContent},
|
||||||
peer::Peer,
|
peer::Peer,
|
||||||
types::{AppId, Element, ElementContent, ElementId, PotId, Tag},
|
types::{AppId, Element, ElementContent, ElementId, FamilyId, PeerId, PotId, Tag},
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
|
@ -101,7 +101,7 @@ impl State {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_peer(&self, peer: Peer) -> anyhow::Result<()> {
|
pub fn add_peer(&self, peer: Peer) -> anyhow::Result<()> {
|
||||||
self.db.add_peer(peer)
|
self.db.add_peer(peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +127,28 @@ impl State {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_family_member(&self, peer: PeerId) -> anyhow::Result<()> {
|
||||||
|
let my_id = self
|
||||||
|
.comm_handle
|
||||||
|
.read()
|
||||||
|
.map_err(|_| Error::msg("Failed to lock on CommHandle"))?
|
||||||
|
.to_owned()
|
||||||
|
.ok_or(Error::msg("CommHandle not initialized"))?
|
||||||
|
.own_peer_id()?;
|
||||||
|
|
||||||
|
if self.db.get_family_of_peer(my_id.clone())?.is_none() {
|
||||||
|
self.db
|
||||||
|
.add_peer_family(FamilyId::new(), None, vec![my_id.clone()])?;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.db.add_peer_to_family(
|
||||||
|
peer,
|
||||||
|
self.db
|
||||||
|
.get_family_of_peer(my_id)?
|
||||||
|
.ok_or(Error::msg("Could not find own family"))?,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_event_receiver(
|
pub fn get_event_receiver(
|
||||||
&self,
|
&self,
|
||||||
app: &AppId,
|
app: &AppId,
|
||||||
|
|
|
@ -23,7 +23,7 @@ async fn two_nodes_element_creation() {
|
||||||
c2.api_config.port = Some(9982);
|
c2.api_config.port = Some(9982);
|
||||||
let ubi1 = Ubisync::new(&Config::default()).await.unwrap();
|
let ubi1 = Ubisync::new(&Config::default()).await.unwrap();
|
||||||
let ubi2 = Arc::new(Ubisync::new(&c2).await.unwrap());
|
let ubi2 = Arc::new(Ubisync::new(&c2).await.unwrap());
|
||||||
ubi1.add_peer_from_id(ubi2.get_destination().unwrap().into())
|
ubi1.add_family_member_from_id(ubi2.get_destination().unwrap().into())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let api_client1 =
|
let api_client1 =
|
||||||
|
@ -92,7 +92,7 @@ async fn two_nodes_api_event() {
|
||||||
c2.api_config.port = Some(9982);
|
c2.api_config.port = Some(9982);
|
||||||
let ubi1 = Arc::new(Ubisync::new(&Config::default()).await.unwrap());
|
let ubi1 = Arc::new(Ubisync::new(&Config::default()).await.unwrap());
|
||||||
let ubi2 = Ubisync::new(&c2).await.unwrap();
|
let ubi2 = Ubisync::new(&c2).await.unwrap();
|
||||||
ubi2.add_peer_from_id(ubi1.get_destination().unwrap().into())
|
ubi2.add_family_member_from_id(ubi1.get_destination().unwrap().into())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let api_client1 =
|
let api_client1 =
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue