mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
holding opened file handler
This commit is contained in:
parent
30a7149764
commit
c5d1a90009
@ -13,8 +13,10 @@ flowy-derive = { path = "../flowy-derive" }
|
||||
flowy-database = { path = "../flowy-database" }
|
||||
flowy-infra = { path = "../flowy-infra" }
|
||||
flowy-observable = { path = "../flowy-observable" }
|
||||
flowy-ot = { path = "../flowy-ot" }
|
||||
flowy-net = { path = "../flowy-net", features = ["flowy_request"] }
|
||||
|
||||
|
||||
diesel = {version = "1.4.7", features = ["sqlite"]}
|
||||
diesel_derives = {version = "1.4.1", features = ["sqlite"]}
|
||||
protobuf = {version = "2.18.0"}
|
||||
@ -26,6 +28,7 @@ tracing = { version = "0.1", features = ["log"] }
|
||||
bytes = { version = "1.0" }
|
||||
strum = "0.21"
|
||||
strum_macros = "0.21"
|
||||
dashmap = "4.0"
|
||||
|
||||
[dev-dependencies]
|
||||
flowy-test = { path = "../flowy-test" }
|
||||
|
@ -10,3 +10,7 @@ impl DocId {
|
||||
Ok(Self(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for DocId {
|
||||
fn as_ref(&self) -> &str { &self.0 }
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
use crate::services::file_manager::FileError;
|
||||
use bytes::Bytes;
|
||||
use derive_more::Display;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
@ -53,10 +52,6 @@ impl std::convert::From<flowy_database::Error> for DocError {
|
||||
// fn from(error: r2d2::Error) -> Self {
|
||||
// ErrorBuilder::new(ErrorCode::InternalError).error(error).build() } }
|
||||
|
||||
impl std::convert::From<FileError> for DocError {
|
||||
fn from(error: FileError) -> Self { ErrorBuilder::new(ErrorCode::InternalError).error(error).build() }
|
||||
}
|
||||
|
||||
// impl std::convert::From<flowy_sqlite::Error> for DocError {
|
||||
// fn from(error: flowy_sqlite::Error) -> Self {
|
||||
// ErrorBuilder::new(ErrorCode::InternalError).error(error).build() } }
|
||||
|
@ -1,8 +1,11 @@
|
||||
use crate::{
|
||||
errors::DocError,
|
||||
services::{doc_controller::DocController, file_manager::FileManager, server::construct_doc_server},
|
||||
services::{doc_controller::DocController, doc_manager::DocManager, server::construct_doc_server},
|
||||
};
|
||||
|
||||
use crate::entities::doc::{CreateDocParams, Doc, QueryDocParams, UpdateDocParams};
|
||||
use diesel::SqliteConnection;
|
||||
use flowy_database::ConnectionPool;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
@ -16,21 +19,37 @@ pub enum DocumentType {
|
||||
Doc,
|
||||
}
|
||||
|
||||
pub struct Document {
|
||||
user: Arc<dyn DocumentUser>,
|
||||
file_manager: RwLock<FileManager>,
|
||||
pub doc: Arc<DocController>,
|
||||
pub struct FlowyDocument {
|
||||
controller: Arc<DocController>,
|
||||
manager: Arc<DocManager>,
|
||||
}
|
||||
|
||||
impl Document {
|
||||
pub fn new(user: Arc<dyn DocumentUser>) -> Document {
|
||||
impl FlowyDocument {
|
||||
pub fn new(user: Arc<dyn DocumentUser>) -> FlowyDocument {
|
||||
let server = construct_doc_server();
|
||||
let doc_controller = Arc::new(DocController::new(server.clone(), user.clone()));
|
||||
let file_manager = RwLock::new(FileManager::new(user.clone()));
|
||||
Self {
|
||||
user,
|
||||
file_manager,
|
||||
doc: doc_controller,
|
||||
}
|
||||
let manager = Arc::new(DocManager::new());
|
||||
let controller = Arc::new(DocController::new(server.clone(), user.clone()));
|
||||
Self { controller, manager }
|
||||
}
|
||||
|
||||
pub fn create(&self, params: CreateDocParams, conn: &SqliteConnection) -> Result<(), DocError> {
|
||||
let _ = self.controller.create(params, conn)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn delete(&self, params: QueryDocParams, conn: &SqliteConnection) -> Result<(), DocError> {
|
||||
let _ = self.controller.delete(params.into(), conn)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn open(&self, params: QueryDocParams, pool: Arc<ConnectionPool>) -> Result<Doc, DocError> {
|
||||
let doc = self.controller.open(params, pool).await?;
|
||||
|
||||
Ok(doc)
|
||||
}
|
||||
|
||||
pub fn update(&self, params: UpdateDocParams, conn: &SqliteConnection) -> Result<(), DocError> {
|
||||
let _ = self.controller.update(params, conn)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,65 @@
|
||||
use crate::errors::{DocError, ErrorBuilder, ErrorCode};
|
||||
use dashmap::{mapref::one::Ref, DashMap};
|
||||
use flowy_ot::{
|
||||
client::{Document, FlowyDoc},
|
||||
core::Delta,
|
||||
};
|
||||
use std::convert::TryInto;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct DocId(pub(crate) String);
|
||||
|
||||
pub struct DocInfo {
|
||||
document: Document,
|
||||
}
|
||||
|
||||
impl std::convert::From<String> for DocId {
|
||||
fn from(s: String) -> Self { DocId(s) }
|
||||
}
|
||||
|
||||
pub(crate) struct DocManager {
|
||||
inner: DashMap<DocId, RwLock<DocInfo>>,
|
||||
}
|
||||
|
||||
impl DocManager {
|
||||
pub(crate) fn new() -> Self { Self { inner: DashMap::new() } }
|
||||
pub(crate) fn open<T, D>(&self, id: T, data: D) -> Result<(), DocError>
|
||||
where
|
||||
T: Into<DocId>,
|
||||
D: TryInto<Delta, Error = DocError>,
|
||||
{
|
||||
let doc_id = id.into();
|
||||
let delta = data.try_into()?;
|
||||
let document = Document::from_delta(delta);
|
||||
let doc_info = DocInfo { document };
|
||||
self.inner.insert(doc_id, RwLock::new(doc_info));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn mut_doc<T, F>(&self, id: T, f: F) -> Result<(), DocError>
|
||||
where
|
||||
T: Into<DocId>,
|
||||
F: FnOnce(&mut Document) -> Result<(), DocError>,
|
||||
{
|
||||
let doc_id = id.into();
|
||||
match self.inner.get(&doc_id) {
|
||||
None => Err(ErrorBuilder::new(ErrorCode::DocNotfound)
|
||||
.msg("Doc is close or you should call open first")
|
||||
.build()),
|
||||
Some(doc_info) => {
|
||||
let mut write_guard = doc_info.write().await;
|
||||
f(&mut write_guard.document)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn close<T>(&self, id: T) -> Result<(), DocError>
|
||||
where
|
||||
T: Into<DocId>,
|
||||
{
|
||||
let doc_id = id.into();
|
||||
self.inner.remove(&doc_id);
|
||||
Ok(())
|
||||
}
|
||||
}
|
3
rust-lib/flowy-document/src/services/doc_manager/mod.rs
Normal file
3
rust-lib/flowy-document/src/services/doc_manager/mod.rs
Normal file
@ -0,0 +1,3 @@
|
||||
mod doc_manager;
|
||||
|
||||
pub use doc_manager::*;
|
@ -1,3 +1,3 @@
|
||||
pub mod doc_controller;
|
||||
pub mod file_manager;
|
||||
pub(crate) mod doc_manager;
|
||||
pub mod server;
|
||||
|
@ -8,9 +8,9 @@ mod delete;
|
||||
mod format;
|
||||
mod insert;
|
||||
|
||||
pub type InsertExtension = Box<dyn InsertExt>;
|
||||
pub type FormatExtension = Box<dyn FormatExt>;
|
||||
pub type DeleteExtension = Box<dyn DeleteExt>;
|
||||
pub type InsertExtension = Box<dyn InsertExt + Send + Sync>;
|
||||
pub type FormatExtension = Box<dyn FormatExt + Send + Sync>;
|
||||
pub type DeleteExtension = Box<dyn DeleteExt + Send + Sync>;
|
||||
|
||||
pub trait InsertExt {
|
||||
fn ext_name(&self) -> &str;
|
||||
|
@ -1,7 +1,7 @@
|
||||
use flowy_dispatch::prelude::Module;
|
||||
|
||||
use crate::deps_resolve::{EditorUserImpl, WorkspaceDatabaseImpl, WorkspaceUserImpl};
|
||||
use flowy_document::module::Document;
|
||||
use flowy_document::module::FlowyDocument;
|
||||
use flowy_user::services::user::UserSessionBuilder;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -24,7 +24,7 @@ pub fn build_modules(config: ModuleConfig) -> Vec<Module> {
|
||||
user_session: user_session.clone(),
|
||||
});
|
||||
|
||||
let document = Arc::new(Document::new(editor_user));
|
||||
let document = Arc::new(FlowyDocument::new(editor_user));
|
||||
|
||||
vec![
|
||||
flowy_user::module::create(user_session),
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
};
|
||||
use flowy_database::DBConnection;
|
||||
use flowy_dispatch::prelude::*;
|
||||
use flowy_document::module::Document;
|
||||
use flowy_document::module::FlowyDocument;
|
||||
use flowy_sqlite::ConnectionPool;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -29,7 +29,7 @@ pub trait WorkspaceDatabase: Send + Sync {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create(user: Arc<dyn WorkspaceUser>, database: Arc<dyn WorkspaceDatabase>, document: Arc<Document>) -> Module {
|
||||
pub fn create(user: Arc<dyn WorkspaceUser>, database: Arc<dyn WorkspaceDatabase>, document: Arc<FlowyDocument>) -> Module {
|
||||
let server = construct_workspace_server();
|
||||
let view_controller = Arc::new(ViewController::new(user.clone(), database.clone(), server.clone(), document));
|
||||
let app_controller = Arc::new(AppController::new(user.clone(), database.clone(), server.clone()));
|
||||
|
@ -15,7 +15,7 @@ use crate::{
|
||||
use flowy_database::SqliteConnection;
|
||||
use flowy_document::{
|
||||
entities::doc::{CreateDocParams, Doc, QueryDocParams, UpdateDocParams},
|
||||
module::Document,
|
||||
module::FlowyDocument,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -24,11 +24,16 @@ pub(crate) struct ViewController {
|
||||
sql: Arc<ViewTableSql>,
|
||||
server: Server,
|
||||
database: Arc<dyn WorkspaceDatabase>,
|
||||
document: Arc<Document>,
|
||||
document: Arc<FlowyDocument>,
|
||||
}
|
||||
|
||||
impl ViewController {
|
||||
pub(crate) fn new(user: Arc<dyn WorkspaceUser>, database: Arc<dyn WorkspaceDatabase>, server: Server, document: Arc<Document>) -> Self {
|
||||
pub(crate) fn new(
|
||||
user: Arc<dyn WorkspaceUser>,
|
||||
database: Arc<dyn WorkspaceDatabase>,
|
||||
server: Server,
|
||||
document: Arc<FlowyDocument>,
|
||||
) -> Self {
|
||||
let sql = Arc::new(ViewTableSql {});
|
||||
Self {
|
||||
user,
|
||||
@ -45,7 +50,7 @@ impl ViewController {
|
||||
// TODO: rollback anything created before if failed?
|
||||
conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
||||
let _ = self.save_view(view.clone(), conn)?;
|
||||
self.document.doc.create(CreateDocParams::new(&view.id, ¶ms.data), conn)?;
|
||||
self.document.create(CreateDocParams::new(&view.id, ¶ms.data), conn)?;
|
||||
|
||||
let repeated_view = self.read_local_views_belong_to(&view.belong_to_id, conn)?;
|
||||
notify(&view.belong_to_id, WorkspaceObservable::AppCreateView)
|
||||
@ -72,7 +77,7 @@ impl ViewController {
|
||||
}
|
||||
|
||||
pub(crate) async fn open_view(&self, params: QueryDocParams) -> Result<Doc, WorkspaceError> {
|
||||
let doc = self.document.doc.open(params, self.database.db_pool()?).await?;
|
||||
let doc = self.document.open(params, self.database.db_pool()?).await?;
|
||||
Ok(doc)
|
||||
}
|
||||
|
||||
@ -82,7 +87,7 @@ impl ViewController {
|
||||
|
||||
conn.immediate_transaction::<_, WorkspaceError, _>(|| {
|
||||
let view_table = self.sql.delete_view(¶ms.view_id, conn)?;
|
||||
let _ = self.document.doc.delete(params.into(), conn)?;
|
||||
let _ = self.document.delete(params.into(), conn)?;
|
||||
|
||||
let repeated_view = self.read_local_views_belong_to(&view_table.belong_to_id, conn)?;
|
||||
notify(&view_table.belong_to_id, WorkspaceObservable::AppDeleteView)
|
||||
@ -121,7 +126,7 @@ impl ViewController {
|
||||
|
||||
pub(crate) async fn update_view_data(&self, params: UpdateDocParams) -> Result<(), WorkspaceError> {
|
||||
let conn = &*self.database.db_connection()?;
|
||||
let _ = self.document.doc.update(params, &*conn)?;
|
||||
let _ = self.document.update(params, &*conn)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user