Finish optimizing channel representations and operations
This commit is contained in:
parent
5f9c56c8b0
commit
dadad397ef
10 changed files with 132 additions and 118 deletions
|
@ -14,7 +14,10 @@ use collections::{BTreeMap, HashMap, HashSet};
|
|||
use dashmap::DashMap;
|
||||
use futures::StreamExt;
|
||||
use rand::{prelude::StdRng, Rng, SeedableRng};
|
||||
use rpc::{proto::{self}, ConnectionId};
|
||||
use rpc::{
|
||||
proto::{self},
|
||||
ConnectionId,
|
||||
};
|
||||
use sea_orm::{
|
||||
entity::prelude::*, ActiveValue, Condition, ConnectionTrait, DatabaseConnection,
|
||||
DatabaseTransaction, DbErr, FromQueryResult, IntoActiveModel, IsolationLevel, JoinType,
|
||||
|
|
|
@ -375,10 +375,7 @@ impl Database {
|
|||
}
|
||||
}
|
||||
|
||||
Ok(ChannelGraph {
|
||||
channels,
|
||||
edges,
|
||||
})
|
||||
Ok(ChannelGraph { channels, edges })
|
||||
}
|
||||
|
||||
pub async fn get_channels_for_user(&self, user_id: UserId) -> Result<ChannelsForUser> {
|
||||
|
@ -394,12 +391,16 @@ impl Database {
|
|||
.all(&*tx)
|
||||
.await?;
|
||||
|
||||
self.get_user_channels(channel_memberships, user_id, &tx).await
|
||||
self.get_user_channels(channel_memberships, &tx).await
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_channel_for_user(&self, channel_id: ChannelId, user_id: UserId) -> Result<ChannelsForUser> {
|
||||
pub async fn get_channel_for_user(
|
||||
&self,
|
||||
channel_id: ChannelId,
|
||||
user_id: UserId,
|
||||
) -> Result<ChannelsForUser> {
|
||||
self.transaction(|tx| async move {
|
||||
let tx = tx;
|
||||
|
||||
|
@ -413,12 +414,16 @@ impl Database {
|
|||
.all(&*tx)
|
||||
.await?;
|
||||
|
||||
self.get_user_channels(channel_membership, user_id, &tx).await
|
||||
self.get_user_channels(channel_membership, &tx).await
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_user_channels(&self, channel_memberships: Vec<channel_member::Model>, user_id: UserId, tx: &DatabaseTransaction) -> Result<ChannelsForUser> {
|
||||
pub async fn get_user_channels(
|
||||
&self,
|
||||
channel_memberships: Vec<channel_member::Model>,
|
||||
tx: &DatabaseTransaction,
|
||||
) -> Result<ChannelsForUser> {
|
||||
let parents_by_child_id = self
|
||||
.get_channel_descendants(channel_memberships.iter().map(|m| m.channel_id), &*tx)
|
||||
.await?;
|
||||
|
@ -824,9 +829,9 @@ impl Database {
|
|||
self.check_user_is_channel_admin(to, user, &*tx).await?;
|
||||
|
||||
let to_ancestors = self.get_channel_ancestors(to, &*tx).await?;
|
||||
let mut from_descendants = self.get_channel_descendants([channel], &*tx).await?;
|
||||
let mut channel_descendants = self.get_channel_descendants([channel], &*tx).await?;
|
||||
for ancestor in to_ancestors {
|
||||
if from_descendants.contains_key(&ancestor) {
|
||||
if channel_descendants.contains_key(&ancestor) {
|
||||
return Err(anyhow!("Cannot create a channel cycle").into());
|
||||
}
|
||||
}
|
||||
|
@ -853,15 +858,17 @@ impl Database {
|
|||
],
|
||||
);
|
||||
tx.execute(channel_paths_stmt).await?;
|
||||
for (from_id, to_ids) in from_descendants.iter().filter(|(id, _)| id != &&channel) {
|
||||
for to_id in to_ids.iter() {
|
||||
for (descdenant_id, descendant_parent_ids) in
|
||||
channel_descendants.iter().filter(|(id, _)| id != &&channel)
|
||||
{
|
||||
for descendant_parent_id in descendant_parent_ids.iter() {
|
||||
let channel_paths_stmt = Statement::from_sql_and_values(
|
||||
self.pool.get_database_backend(),
|
||||
sql,
|
||||
[
|
||||
from_id.to_proto().into(),
|
||||
from_id.to_proto().into(),
|
||||
to_id.to_proto().into(),
|
||||
descdenant_id.to_proto().into(),
|
||||
descdenant_id.to_proto().into(),
|
||||
descendant_parent_id.to_proto().into(),
|
||||
],
|
||||
);
|
||||
tx.execute(channel_paths_stmt).await?;
|
||||
|
@ -883,14 +890,14 @@ impl Database {
|
|||
tx.execute(channel_paths_stmt).await?;
|
||||
}
|
||||
|
||||
if let Some(channel) = from_descendants.get_mut(&channel) {
|
||||
if let Some(channel) = channel_descendants.get_mut(&channel) {
|
||||
// Remove the other parents
|
||||
channel.clear();
|
||||
channel.insert(to);
|
||||
}
|
||||
|
||||
let channels = self
|
||||
.get_channel_graph(from_descendants, false, &*tx)
|
||||
.get_channel_graph(channel_descendants, false, &*tx)
|
||||
.await?;
|
||||
|
||||
Ok(channels)
|
||||
|
@ -1009,8 +1016,16 @@ impl PartialEq for ChannelGraph {
|
|||
// Order independent comparison for tests
|
||||
let channels_set = self.channels.iter().collect::<HashSet<_>>();
|
||||
let other_channels_set = other.channels.iter().collect::<HashSet<_>>();
|
||||
let edges_set = self.edges.iter().map(|edge| (edge.channel_id, edge.parent_id)).collect::<HashSet<_>>();
|
||||
let other_edges_set = other.edges.iter().map(|edge| (edge.channel_id, edge.parent_id)).collect::<HashSet<_>>();
|
||||
let edges_set = self
|
||||
.edges
|
||||
.iter()
|
||||
.map(|edge| (edge.channel_id, edge.parent_id))
|
||||
.collect::<HashSet<_>>();
|
||||
let other_edges_set = other
|
||||
.edges
|
||||
.iter()
|
||||
.map(|edge| (edge.channel_id, edge.parent_id))
|
||||
.collect::<HashSet<_>>();
|
||||
|
||||
channels_set == other_channels_set && edges_set == other_edges_set
|
||||
}
|
||||
|
@ -1023,7 +1038,6 @@ impl PartialEq for ChannelGraph {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
struct SmallSet<T>(SmallVec<[T; 1]>);
|
||||
|
||||
impl<T> Deref for SmallSet<T> {
|
||||
|
|
|
@ -5,7 +5,7 @@ use rpc::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
db::{queries::channels::ChannelGraph, ChannelId, Database, NewUserParams, tests::graph},
|
||||
db::{queries::channels::ChannelGraph, tests::graph, ChannelId, Database, NewUserParams},
|
||||
test_both_dbs,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
|
|
@ -3,8 +3,8 @@ mod connection_pool;
|
|||
use crate::{
|
||||
auth,
|
||||
db::{
|
||||
self, ChannelId, ChannelsForUser, Database, MessageId, ProjectId, RoomId,
|
||||
ServerId, User, UserId,
|
||||
self, ChannelId, ChannelsForUser, Database, MessageId, ProjectId, RoomId, ServerId, User,
|
||||
UserId,
|
||||
},
|
||||
executor::Executor,
|
||||
AppState, Result,
|
||||
|
@ -38,8 +38,8 @@ use lazy_static::lazy_static;
|
|||
use prometheus::{register_int_gauge, IntGauge};
|
||||
use rpc::{
|
||||
proto::{
|
||||
self, Ack, AddChannelBufferCollaborator, AnyTypedEnvelope, EntityMessage, EnvelopedMessage,
|
||||
LiveKitConnectionInfo, RequestMessage, ChannelEdge,
|
||||
self, Ack, AddChannelBufferCollaborator, AnyTypedEnvelope, ChannelEdge, EntityMessage,
|
||||
EnvelopedMessage, LiveKitConnectionInfo, RequestMessage,
|
||||
},
|
||||
Connection, ConnectionId, Peer, Receipt, TypedEnvelope,
|
||||
};
|
||||
|
@ -2213,17 +2213,14 @@ async fn create_channel(
|
|||
|
||||
let update = proto::UpdateChannels {
|
||||
channels: vec![channel],
|
||||
insert_edge: vec![
|
||||
ChannelEdge {
|
||||
parent_id: parent_id.to_proto(),
|
||||
channel_id: id.to_proto(),
|
||||
}
|
||||
],
|
||||
insert_edge: vec![ChannelEdge {
|
||||
parent_id: parent_id.to_proto(),
|
||||
channel_id: id.to_proto(),
|
||||
}],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let user_ids_to_notify =
|
||||
db.get_channel_members(parent_id).await?;
|
||||
let user_ids_to_notify = db.get_channel_members(parent_id).await?;
|
||||
|
||||
let connection_pool = session.connection_pool().await;
|
||||
for user_id in user_ids_to_notify {
|
||||
|
@ -2549,10 +2546,16 @@ async fn respond_to_channel_invite(
|
|||
let result = db.get_channel_for_user(channel_id, session.user_id).await?;
|
||||
update
|
||||
.channels
|
||||
.extend(result.channels.channels.into_iter().map(|channel| proto::Channel {
|
||||
id: channel.id.to_proto(),
|
||||
name: channel.name,
|
||||
}));
|
||||
.extend(
|
||||
result
|
||||
.channels
|
||||
.channels
|
||||
.into_iter()
|
||||
.map(|channel| proto::Channel {
|
||||
id: channel.id.to_proto(),
|
||||
name: channel.name,
|
||||
}),
|
||||
);
|
||||
update.insert_edge = result.channels.edges;
|
||||
update
|
||||
.channel_participants
|
||||
|
@ -2971,7 +2974,7 @@ fn build_initial_channels_update(
|
|||
) -> proto::UpdateChannels {
|
||||
let mut update = proto::UpdateChannels::default();
|
||||
|
||||
for channel in channels.channels.channels{
|
||||
for channel in channels.channels.channels {
|
||||
update.channels.push(proto::Channel {
|
||||
id: channel.id.to_proto(),
|
||||
name: channel.name,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue