refactor flowy-collaboration directories

This commit is contained in:
appflowy 2021-12-25 23:02:20 +08:00
parent 95e0418d97
commit 2b9ce79ed4
44 changed files with 77 additions and 86 deletions

View File

@ -3,13 +3,12 @@ use crate::services::{
persistence::{create_doc, read_doc},
ws_actor::{DocumentWebSocketActor, WSActorMessage},
},
web_socket::{WSClientData, WebSocketReceiver},
web_socket::{WebSocketReceiver, WSClientData},
};
use crate::context::FlowyPersistence;
use backend_service::errors::ServerError;
use flowy_collaboration::{
core::sync::{DocumentPersistence, ServerDocumentManager},
entities::{
doc::{CreateDocParams, DocumentInfo},
revision::{RepeatedRevision, Revision},
@ -25,6 +24,7 @@ use std::{
sync::Arc,
};
use tokio::sync::{mpsc, oneshot};
use flowy_collaboration::sync::{DocumentPersistence, ServerDocumentManager};
pub fn make_document_ws_receiver(persistence: Arc<FlowyPersistence>) -> Arc<DocumentWebSocketReceiver> {
let document_persistence = Arc::new(DocumentPersistenceImpl(persistence.clone()));

View File

@ -7,13 +7,13 @@ use actix_rt::task::spawn_blocking;
use crate::context::FlowyPersistence;
use async_stream::stream;
use backend_service::errors::{internal_error, Result, ServerError};
use flowy_collaboration::{
core::sync::{RevisionUser, ServerDocumentManager, SyncResponse},
protobuf::{DocumentWSData, DocumentWSDataType, NewDocumentUser, Revision},
};
use flowy_collaboration::protobuf::{DocumentWSData, DocumentWSDataType, NewDocumentUser, Revision};
use futures::stream::StreamExt;
use flowy_collaboration::protobuf::RepeatedRevision;
use flowy_collaboration::{
protobuf::RepeatedRevision,
sync::{RevisionUser, ServerDocumentManager, SyncResponse},
};
use std::{convert::TryInto, sync::Arc};
use tokio::sync::{mpsc, oneshot};
@ -93,7 +93,7 @@ impl DocumentWebSocketActor {
DocumentWSDataType::Ack => Ok(()),
DocumentWSDataType::PushRev => self.handle_pushed_rev(user, document_data.data).await,
DocumentWSDataType::PullRev => Ok(()),
DocumentWSDataType::UserConnect => self.handle_user_connect(user, document_data).await,
DocumentWSDataType::UserConnect => Ok(()),
};
match result {
Ok(_) => {},
@ -105,18 +105,6 @@ impl DocumentWebSocketActor {
Ok(())
}
async fn handle_user_connect(&self, user: Arc<ServerDocUser>, document_data: DocumentWSData) -> Result<()> {
let mut new_user = spawn_blocking(move || parse_from_bytes::<NewDocumentUser>(&document_data.data))
.await
.map_err(internal_error)??;
let repeated_revisions =
spawn_blocking(move || parse_from_bytes::<RepeatedRevision>(&new_user.take_revision_data()))
.await
.map_err(internal_error)??;
let _ = self.handle_revision(user, repeated_revisions).await?;
Ok(())
}
async fn handle_pushed_rev(&self, user: Arc<ServerDocUser>, data: Vec<u8>) -> Result<()> {
let repeated_revision = spawn_blocking(move || parse_from_bytes::<RepeatedRevision>(&data))
.await

View File

@ -2,7 +2,7 @@
use crate::util::helper::{ViewTest, *};
use flowy_collaboration::{
core::document::{Document, PlainDoc},
document::{Document, PlainDoc},
entities::{
doc::{CreateDocParams, DocIdentifier},
revision::{md5, RepeatedRevision, RevType, Revision},

View File

@ -4,7 +4,7 @@ use chrono::Utc;
use lazy_static::lazy_static;
use parking_lot::RwLock;
use flowy_collaboration::{core::document::default::initial_read_me, entities::doc::DocumentDelta};
use flowy_collaboration::{document::default::initial_read_me, entities::doc::DocumentDelta};
use flowy_core_data_model::user_default;
use flowy_net::entities::NetworkType;

View File

@ -8,7 +8,7 @@ use crate::{
};
use bytes::Bytes;
use flowy_collaboration::{
core::document::history::UndoResult,
document::history::UndoResult,
entities::{
doc::DocumentDelta,
revision::{RevId, RevType, Revision},

View File

@ -1,7 +1,6 @@
use async_stream::stream;
use flowy_collaboration::{
core::document::{history::UndoResult, Document},
entities::revision::Revision,
errors::CollaborateError,
};
@ -13,6 +12,7 @@ use lib_ot::{
};
use std::sync::Arc;
use tokio::sync::{mpsc, oneshot, RwLock};
use flowy_collaboration::document::{Document, history::UndoResult};
pub(crate) struct EditorCommandQueue {
doc_id: String,

View File

@ -1,5 +1,5 @@
use flowy_collaboration::{
core::document::default::initial_delta_string,
document::default::initial_delta_string,
entities::doc::{CreateDocParams, DocIdentifier, DocumentInfo, ResetDocumentParams},
};
use lib_infra::future::FutureResult;

View File

@ -1,6 +1,6 @@
#![cfg_attr(rustfmt, rustfmt::skip)]
use crate::editor::{TestBuilder, TestOp::*};
use flowy_collaboration::core::document::{FlowyDoc, PlainDoc};
use flowy_collaboration::document::{FlowyDoc, PlainDoc};
use lib_ot::core::{Interval, OperationTransformable, NEW_LINE, WHITESPACE, FlowyStr};
use unicode_segmentation::UnicodeSegmentation;
use lib_ot::rich_text::RichTextDelta;

View File

@ -5,7 +5,7 @@ mod serde_test;
mod undo_redo_test;
use derive_more::Display;
use flowy_collaboration::core::document::{CustomDocument, Document};
use flowy_collaboration::document::{CustomDocument, Document};
use lib_ot::{
core::*,
rich_text::{RichTextAttribute, RichTextAttributes, RichTextDelta},

View File

@ -1,6 +1,6 @@
#![allow(clippy::all)]
use crate::editor::{Rng, TestBuilder, TestOp::*};
use flowy_collaboration::core::document::{FlowyDoc, PlainDoc};
use flowy_collaboration::document::{FlowyDoc, PlainDoc};
use lib_ot::{
core::*,
rich_text::{AttributeBuilder, RichTextAttribute, RichTextAttributes, RichTextDelta},

View File

@ -1,4 +1,4 @@
use flowy_collaboration::core::document::{Document, PlainDoc};
use flowy_collaboration::document::{Document, PlainDoc};
use lib_ot::{
core::*,
rich_text::{AttributeBuilder, RichTextAttribute, RichTextAttributeValue, RichTextDelta},

View File

@ -1,5 +1,5 @@
use crate::editor::{TestBuilder, TestOp::*};
use flowy_collaboration::core::document::{FlowyDoc, PlainDoc, RECORD_THRESHOLD};
use flowy_collaboration::document::{FlowyDoc, PlainDoc, RECORD_THRESHOLD};
use lib_ot::core::{Interval, NEW_LINE, WHITESPACE};
#[test]

View File

@ -1,2 +0,0 @@
pub mod document;
pub mod sync;

View File

@ -1,5 +0,0 @@
mod server_editor;
mod synchronizer;
pub use server_editor::*;
pub use synchronizer::*;

View File

@ -8,13 +8,13 @@ pub fn initial_delta_string() -> String { initial_delta().to_json() }
#[inline]
pub fn initial_read_me() -> RichTextDelta {
let json = include_str!("./READ_ME.json");
let json = include_str!("READ_ME.json");
RichTextDelta::from_json(json).unwrap()
}
#[cfg(test)]
mod tests {
use crate::core::document::default::initial_read_me;
use crate::document::default::initial_read_me;
#[test]
fn load_read_me() {

View File

@ -6,7 +6,7 @@ use lib_ot::{
};
use crate::{
core::document::{
document::{
default::initial_delta,
history::{History, UndoResult},
view::{View, RECORD_THRESHOLD},

View File

@ -1,4 +1,4 @@
use crate::core::document::DeleteExt;
use crate::document::DeleteExt;
use lib_ot::{
core::{DeltaBuilder, Interval},
rich_text::RichTextDelta,

View File

@ -1,4 +1,4 @@
use crate::{core::document::DeleteExt, util::is_newline};
use crate::{document::DeleteExt, util::is_newline};
use lib_ot::{
core::{Attributes, CharMetric, DeltaBuilder, DeltaIter, Interval, NEW_LINE},
rich_text::{plain_attributes, RichTextDelta},

View File

@ -4,7 +4,7 @@ use lib_ot::{
};
use crate::{
core::document::{extensions::helper::line_break, FormatExt},
document::{extensions::helper::line_break, FormatExt},
util::find_newline,
};

View File

@ -4,7 +4,7 @@ use lib_ot::{
};
use crate::{
core::document::{extensions::helper::line_break, FormatExt},
document::{extensions::helper::line_break, FormatExt},
util::find_newline,
};

View File

@ -1,4 +1,4 @@
use crate::{core::document::InsertExt, util::is_newline};
use crate::{document::InsertExt, util::is_newline};
use lib_ot::{
core::{is_empty_line_at_index, DeltaBuilder, DeltaIter},
rich_text::{attributes_except_header, RichTextAttributeKey, RichTextDelta},

View File

@ -1,4 +1,4 @@
use crate::{core::document::InsertExt, util::is_whitespace};
use crate::{document::InsertExt, util::is_whitespace};
use lib_ot::{
core::{count_utf16_code_units, DeltaBuilder, DeltaIter},
rich_text::{plain_attributes, RichTextAttribute, RichTextAttributes, RichTextDelta},

View File

@ -1,4 +1,4 @@
use crate::core::document::InsertExt;
use crate::document::InsertExt;
use lib_ot::{
core::{Attributes, DeltaBuilder, DeltaIter, NEW_LINE},
rich_text::{RichTextAttributeKey, RichTextAttributes, RichTextDelta},

View File

@ -1,4 +1,4 @@
use crate::core::document::InsertExt;
use crate::document::InsertExt;
pub use auto_exit_block::*;
pub use auto_format::*;
pub use default_insert::*;

View File

@ -1,4 +1,4 @@
use crate::{core::document::InsertExt, util::is_newline};
use crate::util::is_newline;
use lib_ot::{
core::{DeltaBuilder, DeltaIter, NEW_LINE},
rich_text::{
@ -10,6 +10,7 @@ use lib_ot::{
RichTextDelta,
},
};
use crate::document::InsertExt;
pub struct PreserveBlockFormatOnInsert {}
impl InsertExt for PreserveBlockFormatOnInsert {

View File

@ -1,5 +1,5 @@
use crate::{
core::document::InsertExt,
document::InsertExt,
util::{contain_newline, is_newline},
};
use lib_ot::{

View File

@ -1,8 +1,9 @@
use crate::{core::document::InsertExt, util::is_newline};
use crate::util::is_newline;
use lib_ot::{
core::{CharMetric, DeltaBuilder, DeltaIter, NEW_LINE},
rich_text::{RichTextAttributeKey, RichTextAttributes, RichTextDelta},
};
use crate::document::InsertExt;
pub struct ResetLineFormatOnNewLine {}
impl InsertExt for ResetLineFormatOnNewLine {

View File

@ -1,4 +1,4 @@
use crate::core::document::*;
use crate::document::*;
use lib_ot::{
core::{trim, Interval},
errors::{ErrorBuilder, OTError, OTErrorCode},

View File

@ -1,4 +1,4 @@
use crate::core::document::default::initial_delta;
use crate::document::default::initial_delta;
use bytes::Bytes;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use lib_ot::rich_text::RichTextDelta;

View File

@ -8,7 +8,7 @@ use std::convert::{TryFrom, TryInto};
#[derive(Debug, Clone, ProtoBuf_Enum, Eq, PartialEq, Hash)]
pub enum DocumentWSDataType {
// The frontend receives the Acked means the backend has accepted the revision
// The frontend receives the Ack means the backend has received the revision
Ack = 0,
// The frontend receives the PushRev event means the backend is pushing the new revision to frontend
PushRev = 1,

View File

@ -1,7 +1,8 @@
pub mod core;
pub mod document;
pub mod entities;
pub mod errors;
pub mod protobuf;
pub mod sync;
pub mod util;
pub use lib_ot::rich_text::RichTextDelta;

View File

@ -540,14 +540,6 @@ impl ::protobuf::reflect::ProtobufValue for NewDocumentUser {
}
}
#[derive(Clone,PartialEq,Eq,Debug,Hash)]
pub enum DocumentWSDataType {
Ack = 0,
PushRev = 1,
PullRev = 2,
UserConnect = 3,
}
impl ::protobuf::ProtobufEnum for DocumentWSDataType {
fn value(&self) -> i32 {
*self as i32
@ -581,6 +573,14 @@ impl ::protobuf::ProtobufEnum for DocumentWSDataType {
}
}
#[derive(Clone,PartialEq,Eq,Debug,Hash)]
pub enum DocumentWSDataType {
Ack = 0,
PushRev = 1,
PullRev = 2,
UserConnect = 3,
}
impl ::std::marker::Copy for DocumentWSDataType {
}

View File

@ -0,0 +1,5 @@
mod server;
mod synchronizer;
pub use server::*;
pub use synchronizer::*;

View File

@ -1,10 +1,8 @@
use crate::{
core::{
document::Document,
sync::{RevisionSynchronizer, RevisionUser},
},
document::Document,
entities::{doc::DocumentInfo, revision::Revision},
errors::{internal_error, CollaborateError, CollaborateResult},
sync::{RevisionSynchronizer, RevisionUser},
};
use async_stream::stream;
use dashmap::DashMap;
@ -96,16 +94,22 @@ impl ServerDocumentManager {
}
struct OpenDocHandle {
sender: mpsc::Sender<EditCommand>,
sender: mpsc::Sender<DocumentCommand>,
persistence: Arc<dyn DocumentPersistence>,
users: DashMap<String, Arc<dyn RevisionUser>>,
}
impl OpenDocHandle {
fn new(doc: DocumentInfo, persistence: Arc<dyn DocumentPersistence>) -> Result<Self, CollaborateError> {
let (sender, receiver) = mpsc::channel(100);
let queue = EditCommandQueue::new(receiver, doc)?;
let users = DashMap::new();
let queue = DocumentCommandQueue::new(receiver, doc)?;
tokio::task::spawn(queue.run());
Ok(Self { sender, persistence })
Ok(Self {
sender,
persistence,
users,
})
}
async fn apply_revisions(
@ -115,7 +119,8 @@ impl OpenDocHandle {
) -> Result<(), CollaborateError> {
let (ret, rx) = oneshot::channel();
let persistence = self.persistence.clone();
let msg = EditCommand::ApplyRevisions {
self.users.insert(user.user_id(), user.clone());
let msg = DocumentCommand::ApplyRevisions {
user,
revisions,
persistence,
@ -127,11 +132,11 @@ impl OpenDocHandle {
pub async fn document_json(&self) -> CollaborateResult<String> {
let (ret, rx) = oneshot::channel();
let msg = EditCommand::GetDocumentJson { ret };
let msg = DocumentCommand::GetDocumentJson { ret };
self.send(msg, rx).await?
}
async fn send<T>(&self, msg: EditCommand, rx: oneshot::Receiver<T>) -> CollaborateResult<T> {
async fn send<T>(&self, msg: DocumentCommand, rx: oneshot::Receiver<T>) -> CollaborateResult<T> {
let _ = self.sender.send(msg).await.map_err(internal_error)?;
let result = rx.await.map_err(internal_error)?;
Ok(result)
@ -139,7 +144,7 @@ impl OpenDocHandle {
}
#[derive(Debug)]
enum EditCommand {
enum DocumentCommand {
ApplyRevisions {
user: Arc<dyn RevisionUser>,
revisions: Vec<Revision>,
@ -151,17 +156,15 @@ enum EditCommand {
},
}
struct EditCommandQueue {
struct DocumentCommandQueue {
pub doc_id: String,
receiver: Option<mpsc::Receiver<EditCommand>>,
receiver: Option<mpsc::Receiver<DocumentCommand>>,
synchronizer: Arc<RevisionSynchronizer>,
users: DashMap<String, Arc<dyn RevisionUser>>,
}
impl EditCommandQueue {
fn new(receiver: mpsc::Receiver<EditCommand>, doc: DocumentInfo) -> Result<Self, CollaborateError> {
impl DocumentCommandQueue {
fn new(receiver: mpsc::Receiver<DocumentCommand>, doc: DocumentInfo) -> Result<Self, CollaborateError> {
let delta = RichTextDelta::from_bytes(&doc.text)?;
let users = DashMap::new();
let synchronizer = Arc::new(RevisionSynchronizer::new(
&doc.id,
doc.rev_id,
@ -172,7 +175,6 @@ impl EditCommandQueue {
doc_id: doc.id,
receiver: Some(receiver),
synchronizer,
users,
})
}
@ -193,22 +195,21 @@ impl EditCommandQueue {
stream.for_each(|msg| self.handle_message(msg)).await;
}
async fn handle_message(&self, msg: EditCommand) {
async fn handle_message(&self, msg: DocumentCommand) {
match msg {
EditCommand::ApplyRevisions {
DocumentCommand::ApplyRevisions {
user,
revisions,
persistence,
ret,
} => {
self.users.insert(user.user_id(), user.clone());
self.synchronizer
.apply_revisions(user, revisions, persistence)
.await
.unwrap();
let _ = ret.send(Ok(()));
},
EditCommand::GetDocumentJson { ret } => {
DocumentCommand::GetDocumentJson { ret } => {
let synchronizer = self.synchronizer.clone();
let json = spawn_blocking(move || synchronizer.doc_json())
.await

View File

@ -1,9 +1,10 @@
use crate::{
core::{document::Document, sync::DocumentPersistence},
document::Document,
entities::{
revision::{Revision, RevisionRange},
ws::{DocumentWSData, DocumentWSDataBuilder},
},
sync::DocumentPersistence,
};
use lib_ot::{core::OperationTransformable, errors::OTError, rich_text::RichTextDelta};
use parking_lot::RwLock;