lib.rs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. mod deps_resolve;
  2. // mod flowy_server;
  3. pub mod module;
  4. use crate::deps_resolve::WorkspaceDepsResolver;
  5. use backend_service::config::ServerConfig;
  6. use flowy_document::module::FlowyDocument;
  7. use flowy_user::{
  8. prelude::UserStatus,
  9. services::user::{UserSession, UserSessionConfig},
  10. };
  11. use flowy_workspace::{errors::WorkspaceError, prelude::WorkspaceController};
  12. use lib_dispatch::prelude::*;
  13. use lib_infra::entities::network_state::NetworkType;
  14. use module::mk_modules;
  15. pub use module::*;
  16. use std::sync::{
  17. atomic::{AtomicBool, Ordering},
  18. Arc,
  19. };
  20. use tokio::sync::broadcast;
  21. static INIT_LOG: AtomicBool = AtomicBool::new(false);
  22. #[derive(Debug, Clone)]
  23. pub struct FlowySDKConfig {
  24. name: String,
  25. root: String,
  26. log_filter: String,
  27. server_config: ServerConfig,
  28. }
  29. impl FlowySDKConfig {
  30. pub fn new(root: &str, server_config: ServerConfig, name: &str) -> Self {
  31. FlowySDKConfig {
  32. name: name.to_owned(),
  33. root: root.to_owned(),
  34. log_filter: crate_log_filter(None),
  35. server_config,
  36. }
  37. }
  38. pub fn log_filter(mut self, filter: &str) -> Self {
  39. self.log_filter = crate_log_filter(Some(filter.to_owned()));
  40. self
  41. }
  42. }
  43. fn crate_log_filter(level: Option<String>) -> String {
  44. let level = level.unwrap_or_else(|| std::env::var("RUST_LOG").unwrap_or_else(|_| "info".to_owned()));
  45. let mut filters = vec![];
  46. filters.push(format!("flowy_sdk={}", level));
  47. filters.push(format!("flowy_workspace={}", level));
  48. filters.push(format!("flowy_user={}", level));
  49. filters.push(format!("flowy_document={}", level));
  50. filters.push(format!("flowy_document_infra={}", level));
  51. filters.push(format!("dart_notify={}", level));
  52. filters.push(format!("lib_ot={}", level));
  53. filters.push(format!("lib_ws={}", level));
  54. filters.push(format!("lib_infra={}", level));
  55. filters.join(",")
  56. }
  57. #[derive(Clone)]
  58. pub struct FlowySDK {
  59. #[allow(dead_code)]
  60. config: FlowySDKConfig,
  61. pub user_session: Arc<UserSession>,
  62. pub flowy_document: Arc<FlowyDocument>,
  63. pub workspace_ctrl: Arc<WorkspaceController>,
  64. pub dispatcher: Arc<EventDispatcher>,
  65. }
  66. impl FlowySDK {
  67. pub fn new(config: FlowySDKConfig) -> Self {
  68. init_log(&config);
  69. init_kv(&config.root);
  70. tracing::debug!("🔥 {:?}", config);
  71. let session_cache_key = format!("{}_session_cache", &config.name);
  72. let user_config = UserSessionConfig::new(&config.root, &config.server_config, &session_cache_key);
  73. let user_session = Arc::new(UserSession::new(user_config));
  74. let flowy_document = mk_document_module(user_session.clone(), &config.server_config);
  75. let workspace_ctrl =
  76. mk_workspace_controller(user_session.clone(), flowy_document.clone(), &config.server_config);
  77. let modules = mk_modules(workspace_ctrl.clone(), user_session.clone());
  78. let dispatcher = Arc::new(EventDispatcher::construct(|| modules));
  79. _init(&dispatcher, user_session.clone(), workspace_ctrl.clone());
  80. Self {
  81. config,
  82. user_session,
  83. flowy_document,
  84. workspace_ctrl,
  85. dispatcher,
  86. }
  87. }
  88. pub fn dispatcher(&self) -> Arc<EventDispatcher> { self.dispatcher.clone() }
  89. }
  90. fn _init(dispatch: &EventDispatcher, user_session: Arc<UserSession>, workspace_controller: Arc<WorkspaceController>) {
  91. let user_status_subscribe = user_session.notifier.user_status_subscribe();
  92. let network_status_subscribe = user_session.notifier.network_type_subscribe();
  93. let cloned_workspace_controller = workspace_controller.clone();
  94. dispatch.spawn(async move {
  95. user_session.init();
  96. _listen_user_status(user_status_subscribe, workspace_controller.clone()).await;
  97. });
  98. dispatch.spawn(async move {
  99. _listen_network_status(network_status_subscribe, cloned_workspace_controller).await;
  100. });
  101. }
  102. async fn _listen_user_status(
  103. mut subscribe: broadcast::Receiver<UserStatus>,
  104. workspace_controller: Arc<WorkspaceController>,
  105. ) {
  106. while let Ok(status) = subscribe.recv().await {
  107. let result = || async {
  108. match status {
  109. UserStatus::Login { token } => {
  110. let _ = workspace_controller.user_did_sign_in(&token).await?;
  111. },
  112. UserStatus::Logout { .. } => {
  113. workspace_controller.user_did_logout().await;
  114. },
  115. UserStatus::Expired { .. } => {
  116. workspace_controller.user_session_expired().await;
  117. },
  118. UserStatus::SignUp { profile, ret } => {
  119. let _ = workspace_controller.user_did_sign_up(&profile.token).await?;
  120. let _ = ret.send(());
  121. },
  122. }
  123. Ok::<(), WorkspaceError>(())
  124. };
  125. match result().await {
  126. Ok(_) => {},
  127. Err(e) => log::error!("{}", e),
  128. }
  129. }
  130. }
  131. async fn _listen_network_status(
  132. mut subscribe: broadcast::Receiver<NetworkType>,
  133. workspace_controller: Arc<WorkspaceController>,
  134. ) {
  135. while let Ok(new_type) = subscribe.recv().await {
  136. workspace_controller.network_state_changed(new_type);
  137. }
  138. }
  139. fn init_kv(root: &str) {
  140. match lib_infra::kv::KV::init(root) {
  141. Ok(_) => {},
  142. Err(e) => tracing::error!("Init kv store failedL: {}", e),
  143. }
  144. }
  145. fn init_log(config: &FlowySDKConfig) {
  146. if !INIT_LOG.load(Ordering::SeqCst) {
  147. INIT_LOG.store(true, Ordering::SeqCst);
  148. let _ = lib_log::Builder::new("flowy-client", &config.root)
  149. .env_filter(&config.log_filter)
  150. .build();
  151. }
  152. }
  153. fn mk_workspace_controller(
  154. user_session: Arc<UserSession>,
  155. flowy_document: Arc<FlowyDocument>,
  156. server_config: &ServerConfig,
  157. ) -> Arc<WorkspaceController> {
  158. let workspace_deps = WorkspaceDepsResolver::new(user_session);
  159. let (user, database) = workspace_deps.split_into();
  160. flowy_workspace::module::init_workspace_controller(user, database, flowy_document, server_config)
  161. }