2023-05-21 18:53:59 +08:00
|
|
|
#![allow(unused_doc_comments)]
|
|
|
|
|
2023-08-14 12:57:59 +08:00
|
|
|
use std::sync::Weak;
|
2023-04-28 14:08:53 +08:00
|
|
|
use std::time::Duration;
|
2023-10-02 09:12:24 +02:00
|
|
|
use std::{fmt, sync::Arc};
|
2023-04-28 14:08:53 +08:00
|
|
|
|
2023-05-17 09:49:39 +08:00
|
|
|
use tokio::sync::RwLock;
|
2023-10-10 19:05:55 +08:00
|
|
|
use tracing::error;
|
2023-04-04 08:41:16 +08:00
|
|
|
|
2023-09-17 17:14:34 +08:00
|
|
|
use collab_integrate::collab_builder::{AppFlowyCollabBuilder, CollabSource};
|
2023-07-29 09:46:24 +08:00
|
|
|
use flowy_database2::DatabaseManager;
|
|
|
|
use flowy_document2::manager::DocumentManager;
|
2023-10-02 09:12:24 +02:00
|
|
|
use flowy_folder2::manager::FolderManager;
|
2023-08-06 11:51:03 +08:00
|
|
|
use flowy_sqlite::kv::StorePreferences;
|
2023-09-01 22:27:29 +08:00
|
|
|
use flowy_storage::FileStorageService;
|
2022-11-13 22:23:57 +08:00
|
|
|
use flowy_task::{TaskDispatcher, TaskRunner};
|
2023-10-02 09:12:24 +02:00
|
|
|
use flowy_user::event_map::UserCloudServiceProvider;
|
2023-08-17 23:46:39 +08:00
|
|
|
use flowy_user::manager::{UserManager, UserSessionConfig};
|
2021-11-19 14:38:11 +08:00
|
|
|
use lib_dispatch::prelude::*;
|
2022-06-27 23:15:43 +08:00
|
|
|
use lib_dispatch::runtime::tokio_default_runtime;
|
2022-12-01 08:35:50 +08:00
|
|
|
use module::make_plugins;
|
2021-07-14 21:12:52 +08:00
|
|
|
pub use module::*;
|
2021-07-09 23:31:44 +08:00
|
|
|
|
2023-04-28 14:08:53 +08:00
|
|
|
use crate::deps_resolve::*;
|
2023-10-02 09:12:24 +02:00
|
|
|
use crate::integrate::collab_interact::CollabInteractImpl;
|
|
|
|
use crate::integrate::log::{create_log_filter, init_log};
|
2023-09-17 17:14:34 +08:00
|
|
|
use crate::integrate::server::{current_server_provider, ServerProvider, ServerType};
|
2023-10-02 09:12:24 +02:00
|
|
|
use crate::integrate::user::UserStatusCallbackImpl;
|
2023-04-28 14:08:53 +08:00
|
|
|
|
|
|
|
mod deps_resolve;
|
2023-05-21 18:53:59 +08:00
|
|
|
mod integrate;
|
2023-04-28 14:08:53 +08:00
|
|
|
pub mod module;
|
|
|
|
|
2023-03-13 16:42:45 +08:00
|
|
|
/// This name will be used as to identify the current [AppFlowyCore] instance.
|
|
|
|
/// Don't change this.
|
|
|
|
pub const DEFAULT_NAME: &str = "appflowy";
|
|
|
|
|
2022-01-07 17:37:11 +08:00
|
|
|
#[derive(Clone)]
|
2023-02-02 23:02:49 +08:00
|
|
|
pub struct AppFlowyCoreConfig {
|
2023-02-13 09:29:49 +08:00
|
|
|
/// Different `AppFlowyCoreConfig` instance should have different name
|
|
|
|
name: String,
|
|
|
|
/// Panics if the `root` path is not existing
|
2023-07-05 20:57:09 +08:00
|
|
|
pub storage_path: String,
|
2023-02-13 09:29:49 +08:00
|
|
|
log_filter: String,
|
2022-01-07 17:37:11 +08:00
|
|
|
}
|
|
|
|
|
2023-02-02 23:02:49 +08:00
|
|
|
impl fmt::Debug for AppFlowyCoreConfig {
|
2023-02-13 09:29:49 +08:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
f.debug_struct("AppFlowyCoreConfig")
|
|
|
|
.field("storage_path", &self.storage_path)
|
|
|
|
.finish()
|
|
|
|
}
|
2021-09-05 13:50:23 +08:00
|
|
|
}
|
|
|
|
|
2023-02-02 23:02:49 +08:00
|
|
|
impl AppFlowyCoreConfig {
|
2023-05-21 18:53:59 +08:00
|
|
|
pub fn new(root: &str, name: String) -> Self {
|
2023-02-13 09:29:49 +08:00
|
|
|
AppFlowyCoreConfig {
|
|
|
|
name,
|
|
|
|
storage_path: root.to_owned(),
|
|
|
|
log_filter: create_log_filter("info".to_owned(), vec![]),
|
2021-09-05 13:50:23 +08:00
|
|
|
}
|
2023-02-13 09:29:49 +08:00
|
|
|
}
|
2021-09-05 13:50:23 +08:00
|
|
|
|
2023-02-13 09:29:49 +08:00
|
|
|
pub fn log_filter(mut self, level: &str, with_crates: Vec<String>) -> Self {
|
|
|
|
self.log_filter = create_log_filter(level.to_owned(), with_crates);
|
|
|
|
self
|
|
|
|
}
|
2021-09-05 13:50:23 +08:00
|
|
|
}
|
|
|
|
|
2021-09-04 15:12:53 +08:00
|
|
|
#[derive(Clone)]
|
2023-02-02 23:02:49 +08:00
|
|
|
pub struct AppFlowyCore {
|
2023-02-13 09:29:49 +08:00
|
|
|
#[allow(dead_code)]
|
|
|
|
pub config: AppFlowyCoreConfig,
|
2023-08-14 12:57:59 +08:00
|
|
|
pub user_manager: Arc<UserManager>,
|
2023-07-29 09:46:24 +08:00
|
|
|
pub document_manager: Arc<DocumentManager>,
|
2023-07-05 20:57:09 +08:00
|
|
|
pub folder_manager: Arc<FolderManager>,
|
2023-07-29 09:46:24 +08:00
|
|
|
pub database_manager: Arc<DatabaseManager>,
|
2023-02-13 09:29:49 +08:00
|
|
|
pub event_dispatcher: Arc<AFPluginDispatcher>,
|
2023-09-17 17:14:34 +08:00
|
|
|
pub server_provider: Arc<ServerProvider>,
|
2023-02-13 09:29:49 +08:00
|
|
|
pub task_dispatcher: Arc<RwLock<TaskDispatcher>>,
|
2023-08-14 12:57:59 +08:00
|
|
|
pub store_preference: Arc<StorePreferences>,
|
2021-07-14 21:12:52 +08:00
|
|
|
}
|
2021-06-28 23:58:43 +08:00
|
|
|
|
2023-02-02 23:02:49 +08:00
|
|
|
impl AppFlowyCore {
|
2023-02-13 09:29:49 +08:00
|
|
|
pub fn new(config: AppFlowyCoreConfig) -> Self {
|
2023-05-21 18:53:59 +08:00
|
|
|
/// The profiling can be used to tracing the performance of the application.
|
|
|
|
/// Check out the [Link](https://appflowy.gitbook.io/docs/essential-documentation/contribute-to-appflowy/architecture/backend/profiling)
|
|
|
|
/// for more information.
|
2023-03-03 20:38:31 +08:00
|
|
|
#[cfg(feature = "profiling")]
|
|
|
|
console_subscriber::init();
|
|
|
|
|
2023-05-21 18:53:59 +08:00
|
|
|
// Init the logger before anything else
|
2023-02-13 09:29:49 +08:00
|
|
|
init_log(&config);
|
2023-05-21 18:53:59 +08:00
|
|
|
|
|
|
|
// Init the key value database
|
2023-08-06 11:51:03 +08:00
|
|
|
let store_preference = Arc::new(StorePreferences::new(&config.storage_path).unwrap());
|
2023-05-21 18:53:59 +08:00
|
|
|
|
2023-07-29 09:46:24 +08:00
|
|
|
tracing::info!("🔥 {:?}", &config);
|
2023-02-13 09:29:49 +08:00
|
|
|
let runtime = tokio_default_runtime().unwrap();
|
|
|
|
let task_scheduler = TaskDispatcher::new(Duration::from_secs(2));
|
|
|
|
let task_dispatcher = Arc::new(RwLock::new(task_scheduler));
|
|
|
|
runtime.spawn(TaskRunner::run(task_dispatcher.clone()));
|
|
|
|
|
2023-08-06 11:51:03 +08:00
|
|
|
let provider_type = current_server_provider(&store_preference);
|
2023-09-17 17:14:34 +08:00
|
|
|
let server_provider = Arc::new(ServerProvider::new(
|
2023-07-14 13:37:13 +08:00
|
|
|
config.clone(),
|
2023-08-06 11:51:03 +08:00
|
|
|
provider_type,
|
|
|
|
Arc::downgrade(&store_preference),
|
2023-07-14 13:37:13 +08:00
|
|
|
));
|
2023-06-06 16:03:29 +08:00
|
|
|
|
2023-07-29 09:46:24 +08:00
|
|
|
let (
|
2023-08-14 12:57:59 +08:00
|
|
|
user_manager,
|
2023-07-29 09:46:24 +08:00
|
|
|
folder_manager,
|
|
|
|
server_provider,
|
|
|
|
database_manager,
|
|
|
|
document_manager,
|
|
|
|
collab_builder,
|
|
|
|
) = runtime.block_on(async {
|
|
|
|
/// The shared collab builder is used to build the [Collab] instance. The plugins will be loaded
|
|
|
|
/// on demand based on the [CollabPluginConfig].
|
2023-08-14 12:57:59 +08:00
|
|
|
let collab_builder = Arc::new(AppFlowyCollabBuilder::new(server_provider.clone()));
|
2023-10-02 09:12:24 +02:00
|
|
|
let user_manager = init_user_manager(
|
2023-08-14 12:57:59 +08:00
|
|
|
&config,
|
|
|
|
&store_preference,
|
2023-07-29 09:46:24 +08:00
|
|
|
server_provider.clone(),
|
2023-08-14 12:57:59 +08:00
|
|
|
Arc::downgrade(&collab_builder),
|
|
|
|
);
|
2023-10-23 11:43:31 +08:00
|
|
|
|
2023-08-14 12:57:59 +08:00
|
|
|
collab_builder
|
|
|
|
.set_snapshot_persistence(Arc::new(SnapshotDBImpl(Arc::downgrade(&user_manager))));
|
2023-07-29 09:46:24 +08:00
|
|
|
|
|
|
|
let database_manager = DatabaseDepsResolver::resolve(
|
2023-08-14 12:57:59 +08:00
|
|
|
Arc::downgrade(&user_manager),
|
2023-07-29 09:46:24 +08:00
|
|
|
task_dispatcher.clone(),
|
|
|
|
collab_builder.clone(),
|
|
|
|
server_provider.clone(),
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
|
|
|
|
let document_manager = DocumentDepsResolver::resolve(
|
2023-08-14 12:57:59 +08:00
|
|
|
Arc::downgrade(&user_manager),
|
2023-07-29 09:46:24 +08:00
|
|
|
&database_manager,
|
|
|
|
collab_builder.clone(),
|
|
|
|
server_provider.clone(),
|
2023-09-01 22:27:29 +08:00
|
|
|
Arc::downgrade(&(server_provider.clone() as Arc<dyn FileStorageService>)),
|
2023-07-29 09:46:24 +08:00
|
|
|
);
|
|
|
|
|
|
|
|
let folder_manager = FolderDepsResolver::resolve(
|
2023-08-14 12:57:59 +08:00
|
|
|
Arc::downgrade(&user_manager),
|
2023-07-29 09:46:24 +08:00
|
|
|
&document_manager,
|
|
|
|
&database_manager,
|
|
|
|
collab_builder.clone(),
|
|
|
|
server_provider.clone(),
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
|
|
|
|
(
|
2023-08-14 12:57:59 +08:00
|
|
|
user_manager,
|
2023-07-29 09:46:24 +08:00
|
|
|
folder_manager,
|
|
|
|
server_provider,
|
|
|
|
database_manager,
|
|
|
|
document_manager,
|
|
|
|
collab_builder,
|
|
|
|
)
|
|
|
|
});
|
2023-02-13 09:29:49 +08:00
|
|
|
|
2023-10-02 09:12:24 +02:00
|
|
|
let user_status_callback = UserStatusCallbackImpl {
|
2023-07-29 09:46:24 +08:00
|
|
|
collab_builder,
|
2023-02-13 09:29:49 +08:00
|
|
|
folder_manager: folder_manager.clone(),
|
2023-02-26 16:27:17 +08:00
|
|
|
database_manager: database_manager.clone(),
|
2023-07-29 09:46:24 +08:00
|
|
|
document_manager: document_manager.clone(),
|
2023-08-12 17:36:31 +08:00
|
|
|
server_provider: server_provider.clone(),
|
2023-02-13 09:29:49 +08:00
|
|
|
config: config.clone(),
|
|
|
|
};
|
2023-05-21 18:53:59 +08:00
|
|
|
|
2023-10-02 09:12:24 +02:00
|
|
|
let collab_interact_impl = CollabInteractImpl {
|
|
|
|
database_manager: Arc::downgrade(&database_manager),
|
|
|
|
document_manager: Arc::downgrade(&document_manager),
|
|
|
|
};
|
|
|
|
|
2023-08-14 12:57:59 +08:00
|
|
|
let cloned_user_session = Arc::downgrade(&user_manager);
|
2023-02-13 09:29:49 +08:00
|
|
|
runtime.block_on(async move {
|
2023-10-23 11:43:31 +08:00
|
|
|
if let Some(user_manager) = cloned_user_session.upgrade() {
|
|
|
|
if let Err(err) = user_manager
|
2023-10-02 09:12:24 +02:00
|
|
|
.init(user_status_callback, collab_interact_impl)
|
2023-10-10 19:05:55 +08:00
|
|
|
.await
|
|
|
|
{
|
|
|
|
error!("Init user failed: {}", err)
|
|
|
|
}
|
2023-07-05 20:57:09 +08:00
|
|
|
}
|
2023-02-13 09:29:49 +08:00
|
|
|
});
|
2021-07-14 21:12:52 +08:00
|
|
|
|
2023-02-13 09:29:49 +08:00
|
|
|
let event_dispatcher = Arc::new(AFPluginDispatcher::construct(runtime, || {
|
|
|
|
make_plugins(
|
2023-07-29 09:46:24 +08:00
|
|
|
Arc::downgrade(&folder_manager),
|
|
|
|
Arc::downgrade(&database_manager),
|
2023-08-14 12:57:59 +08:00
|
|
|
Arc::downgrade(&user_manager),
|
2023-07-29 09:46:24 +08:00
|
|
|
Arc::downgrade(&document_manager),
|
2023-02-13 09:29:49 +08:00
|
|
|
)
|
|
|
|
}));
|
|
|
|
|
|
|
|
Self {
|
|
|
|
config,
|
2023-08-14 12:57:59 +08:00
|
|
|
user_manager,
|
2023-07-29 09:46:24 +08:00
|
|
|
document_manager,
|
2023-02-13 09:29:49 +08:00
|
|
|
folder_manager,
|
2023-02-26 16:27:17 +08:00
|
|
|
database_manager,
|
2023-02-13 09:29:49 +08:00
|
|
|
event_dispatcher,
|
2023-05-21 18:53:59 +08:00
|
|
|
server_provider,
|
2023-02-13 09:29:49 +08:00
|
|
|
task_dispatcher,
|
2023-08-14 12:57:59 +08:00
|
|
|
store_preference,
|
2022-01-23 12:14:00 +08:00
|
|
|
}
|
2023-02-13 09:29:49 +08:00
|
|
|
}
|
|
|
|
|
2023-07-29 09:46:24 +08:00
|
|
|
/// Only expose the dispatcher in test
|
2023-02-13 09:29:49 +08:00
|
|
|
pub fn dispatcher(&self) -> Arc<AFPluginDispatcher> {
|
|
|
|
self.event_dispatcher.clone()
|
|
|
|
}
|
2021-09-04 15:12:53 +08:00
|
|
|
}
|
2021-07-17 10:26:05 +08:00
|
|
|
|
2023-10-02 09:12:24 +02:00
|
|
|
fn init_user_manager(
|
2023-02-13 09:29:49 +08:00
|
|
|
config: &AppFlowyCoreConfig,
|
2023-08-06 11:51:03 +08:00
|
|
|
storage_preference: &Arc<StorePreferences>,
|
2023-05-21 18:53:59 +08:00
|
|
|
user_cloud_service_provider: Arc<dyn UserCloudServiceProvider>,
|
2023-08-14 12:57:59 +08:00
|
|
|
collab_builder: Weak<AppFlowyCollabBuilder>,
|
|
|
|
) -> Arc<UserManager> {
|
2023-02-13 09:29:49 +08:00
|
|
|
let user_config = UserSessionConfig::new(&config.name, &config.storage_path);
|
2023-08-20 14:13:54 +08:00
|
|
|
UserManager::new(
|
2023-08-06 11:51:03 +08:00
|
|
|
user_config,
|
|
|
|
user_cloud_service_provider,
|
|
|
|
storage_preference.clone(),
|
2023-08-14 12:57:59 +08:00
|
|
|
collab_builder,
|
2023-08-20 14:13:54 +08:00
|
|
|
)
|
2021-12-14 15:31:44 +08:00
|
|
|
}
|
2023-01-31 19:30:48 +08:00
|
|
|
|
2023-09-17 17:14:34 +08:00
|
|
|
impl From<ServerType> for CollabSource {
|
2023-10-02 09:12:24 +02:00
|
|
|
fn from(server_type: ServerType) -> Self {
|
|
|
|
match server_type {
|
2023-09-17 17:14:34 +08:00
|
|
|
ServerType::Local => CollabSource::Local,
|
2023-10-02 17:22:22 +08:00
|
|
|
ServerType::AFCloud => CollabSource::AFCloud,
|
2023-09-17 17:14:34 +08:00
|
|
|
ServerType::Supabase => CollabSource::Supabase,
|
2023-05-31 17:42:14 +08:00
|
|
|
}
|
2023-05-23 23:55:21 +08:00
|
|
|
}
|
|
|
|
}
|