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)
|
||||
}
|
||||
|
||||
pub fn own_peer_id(&self) -> anyhow::Result<PeerId> {
|
||||
Ok(self.i2p_address()?.into())
|
||||
}
|
||||
|
||||
fn read_connection(
|
||||
wrapped_stream: Arc<RwLock<I2pStream>>,
|
||||
state: Arc<CommState>,
|
||||
|
|
|
@ -61,14 +61,19 @@ impl Ubisync {
|
|||
|
||||
pub fn add_peer(&self, p: impl TryInto<Peer, Error = anyhow::Error>) -> anyhow::Result<()> {
|
||||
match p.try_into() {
|
||||
Ok(peer) => self.state_handle.set_peer(peer),
|
||||
Ok(peer) => self.state_handle.add_peer(peer),
|
||||
Err(e) => bail!(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_peer_from_id(&self, id: PeerId) -> anyhow::Result<()> {
|
||||
// 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> {
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
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 serde::{Deserialize, Serialize};
|
||||
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};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Collection, PartialEq, Clone)]
|
||||
#[collection(name = "peer-families", views = [])]
|
||||
#[collection(name = "peer-families", views = [DbPeerFamilyByMemberId])]
|
||||
pub(super) struct DbPeerFamily {
|
||||
#[natural_id]
|
||||
pub(super) id: AsKey<FamilyId>,
|
||||
|
@ -17,6 +21,33 @@ pub(super) struct DbPeerFamily {
|
|||
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 {
|
||||
fn from(value: DbPeerFamily) -> Self {
|
||||
Family {
|
||||
|
@ -75,6 +106,19 @@ impl StateDB {
|
|||
.map(|doc_opt| doc_opt.map(|doc| doc.contents.into()))
|
||||
.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)]
|
||||
|
@ -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,
|
||||
messages::{Message, MessageContent},
|
||||
peer::Peer,
|
||||
types::{AppId, Element, ElementContent, ElementId, PotId, Tag},
|
||||
types::{AppId, Element, ElementContent, ElementId, FamilyId, PeerId, PotId, Tag},
|
||||
};
|
||||
|
||||
use anyhow::Error;
|
||||
|
@ -101,7 +101,7 @@ impl State {
|
|||
todo!()
|
||||
}
|
||||
|
||||
pub fn set_peer(&self, peer: Peer) -> anyhow::Result<()> {
|
||||
pub fn add_peer(&self, peer: Peer) -> anyhow::Result<()> {
|
||||
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(
|
||||
&self,
|
||||
app: &AppId,
|
||||
|
|
|
@ -23,7 +23,7 @@ async fn two_nodes_element_creation() {
|
|||
c2.api_config.port = Some(9982);
|
||||
let ubi1 = Ubisync::new(&Config::default()).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();
|
||||
|
||||
let api_client1 =
|
||||
|
@ -92,7 +92,7 @@ async fn two_nodes_api_event() {
|
|||
c2.api_config.port = Some(9982);
|
||||
let ubi1 = Arc::new(Ubisync::new(&Config::default()).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();
|
||||
|
||||
let api_client1 =
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue