mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-10-29 00:51:24 +00:00
134 lines
4.0 KiB
Rust
134 lines
4.0 KiB
Rust
use crate::{
|
|
context::FlowyPersistence,
|
|
services::web_socket::{entities::Socket, WSClientData, WSUser, WebSocketMessage},
|
|
util::serde_ext::parse_from_bytes,
|
|
};
|
|
use actix_rt::task::spawn_blocking;
|
|
use async_stream::stream;
|
|
use backend_service::errors::{internal_error, Result};
|
|
use flowy_collaboration::{
|
|
protobuf::{
|
|
ClientRevisionWSData as ClientRevisionWSDataPB,
|
|
ClientRevisionWSDataType as ClientRevisionWSDataTypePB,
|
|
},
|
|
server_document::ServerDocumentManager,
|
|
synchronizer::{RevisionSyncResponse, RevisionUser},
|
|
};
|
|
use futures::stream::StreamExt;
|
|
use std::sync::Arc;
|
|
use tokio::sync::{mpsc, oneshot};
|
|
|
|
pub enum FolderWSActorMessage {
|
|
ClientData {
|
|
client_data: WSClientData,
|
|
persistence: Arc<FlowyPersistence>,
|
|
ret: oneshot::Sender<Result<()>>,
|
|
},
|
|
}
|
|
|
|
pub struct FolderWebSocketActor {
|
|
receiver: Option<mpsc::Receiver<FolderWSActorMessage>>,
|
|
}
|
|
|
|
impl FolderWebSocketActor {
|
|
pub fn new(receiver: mpsc::Receiver<FolderWSActorMessage>) -> Self {
|
|
Self {
|
|
receiver: Some(receiver),
|
|
}
|
|
}
|
|
|
|
pub async fn run(mut self) {
|
|
let mut receiver = self
|
|
.receiver
|
|
.take()
|
|
.expect("FolderWebSocketActor's receiver should only take one time");
|
|
let stream = stream! {
|
|
loop {
|
|
match receiver.recv().await {
|
|
Some(msg) => yield msg,
|
|
None => break,
|
|
}
|
|
}
|
|
};
|
|
stream.for_each(|msg| self.handle_message(msg)).await;
|
|
}
|
|
|
|
async fn handle_message(&self, msg: FolderWSActorMessage) {
|
|
match msg {
|
|
FolderWSActorMessage::ClientData {
|
|
client_data,
|
|
persistence: _,
|
|
ret,
|
|
} => {
|
|
let _ = ret.send(self.handle_folder_data(client_data).await);
|
|
},
|
|
}
|
|
}
|
|
|
|
async fn handle_folder_data(&self, client_data: WSClientData) -> Result<()> {
|
|
let WSClientData { user, socket, data } = client_data;
|
|
let folder_client_data = spawn_blocking(move || parse_from_bytes::<ClientRevisionWSDataPB>(&data))
|
|
.await
|
|
.map_err(internal_error)??;
|
|
|
|
tracing::debug!(
|
|
"[DocumentWebSocketActor]: receive: {}:{}, {:?}",
|
|
folder_client_data.object_id,
|
|
folder_client_data.data_id,
|
|
folder_client_data.ty
|
|
);
|
|
|
|
let _user = Arc::new(FolderRevisionUser { user, socket });
|
|
match &folder_client_data.ty {
|
|
ClientRevisionWSDataTypePB::ClientPushRev => {
|
|
todo!()
|
|
},
|
|
ClientRevisionWSDataTypePB::ClientPing => {
|
|
todo!()
|
|
},
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct FolderRevisionUser {
|
|
pub user: Arc<WSUser>,
|
|
pub(crate) socket: Socket,
|
|
}
|
|
|
|
impl std::fmt::Debug for FolderRevisionUser {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
f.debug_struct("FolderRevisionUser")
|
|
.field("user", &self.user)
|
|
.field("socket", &self.socket)
|
|
.finish()
|
|
}
|
|
}
|
|
|
|
impl RevisionUser for FolderRevisionUser {
|
|
fn user_id(&self) -> String { self.user.id().to_string() }
|
|
|
|
fn receive(&self, resp: RevisionSyncResponse) {
|
|
let result = match resp {
|
|
RevisionSyncResponse::Pull(data) => {
|
|
let msg: WebSocketMessage = data.into();
|
|
self.socket.try_send(msg).map_err(internal_error)
|
|
},
|
|
RevisionSyncResponse::Push(data) => {
|
|
let msg: WebSocketMessage = data.into();
|
|
self.socket.try_send(msg).map_err(internal_error)
|
|
},
|
|
RevisionSyncResponse::Ack(data) => {
|
|
let msg: WebSocketMessage = data.into();
|
|
self.socket.try_send(msg).map_err(internal_error)
|
|
},
|
|
};
|
|
|
|
match result {
|
|
Ok(_) => {},
|
|
Err(e) => log::error!("[FolderRevisionUser]: {}", e),
|
|
}
|
|
}
|
|
}
|