manager.rs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. use collab::plugin_impl::rocks_disk::RocksDiskPlugin;
  2. use collab::preclude::{Collab, CollabBuilder};
  3. use collab_persistence::kv::rocks_kv::RocksCollabDB;
  4. use flowy_error::{FlowyError, FlowyResult};
  5. use parking_lot::RwLock;
  6. use std::{collections::HashMap, sync::Arc};
  7. use crate::{
  8. document::{Document, DocumentDataWrapper},
  9. entities::{BlockEventPB, DocEventPB},
  10. notification::{send_notification, DocumentNotification},
  11. };
  12. pub trait DocumentUser: Send + Sync {
  13. fn user_id(&self) -> Result<i64, FlowyError>;
  14. fn token(&self) -> Result<String, FlowyError>; // unused now.
  15. fn kv_db(&self) -> Result<Arc<RocksCollabDB>, FlowyError>;
  16. }
  17. pub struct DocumentManager {
  18. documents: Arc<RwLock<HashMap<String, Arc<Document>>>>,
  19. user: Arc<dyn DocumentUser>,
  20. }
  21. // unsafe impl Send for DocumentManager {}
  22. // unsafe impl Sync for DocumentManager {}
  23. impl DocumentManager {
  24. pub fn new(user: Arc<dyn DocumentUser>) -> Self {
  25. Self {
  26. documents: Default::default(),
  27. user,
  28. }
  29. }
  30. pub fn create_document(
  31. &self,
  32. doc_id: String,
  33. data: DocumentDataWrapper,
  34. ) -> FlowyResult<Arc<Document>> {
  35. self.get_document(doc_id, Some(data))
  36. }
  37. fn get_document(
  38. &self,
  39. doc_id: String,
  40. data: Option<DocumentDataWrapper>,
  41. ) -> FlowyResult<Arc<Document>> {
  42. let collab = self.get_collab_for_doc_id(&doc_id)?;
  43. let document = Arc::new(Document::new(collab)?);
  44. self.documents.write().insert(doc_id, document.clone());
  45. if data.is_some() {
  46. // Here use unwrap() is safe, because we have checked data.is_some() before.
  47. // document
  48. // .lock()
  49. // .create_with_data(data.unwrap().0)
  50. // .map_err(|err| FlowyError::internal().context(err))?;
  51. }
  52. Ok(document)
  53. }
  54. pub fn open_document(&self, doc_id: String) -> FlowyResult<Arc<Document>> {
  55. if let Some(doc) = self.documents.read().get(&doc_id) {
  56. return Ok(doc.clone());
  57. }
  58. let document = self.get_document(doc_id.clone(), None)?;
  59. let clone_doc_id = doc_id.clone();
  60. let _document_data = document
  61. .lock()
  62. .open(move |events, is_remote| {
  63. println!("events: {:?}", events);
  64. println!("is_remote: {:?}", is_remote);
  65. send_notification(&clone_doc_id, DocumentNotification::DidReceiveUpdate)
  66. .payload(DocEventPB {
  67. events: events
  68. .iter()
  69. .map(|event| event.to_owned().into())
  70. .collect::<Vec<BlockEventPB>>(),
  71. is_remote: is_remote.to_owned(),
  72. })
  73. .send();
  74. })
  75. .map_err(|err| FlowyError::internal().context(err))?;
  76. Ok(document)
  77. }
  78. pub fn close_document(&self, doc_id: String) -> FlowyResult<()> {
  79. self.documents.write().remove(&doc_id);
  80. Ok(())
  81. }
  82. fn get_collab_for_doc_id(&self, doc_id: &str) -> Result<Collab, FlowyError> {
  83. let uid = self.user.user_id()?;
  84. let kv_db = self.user.kv_db()?;
  85. let mut collab = CollabBuilder::new(uid, doc_id).build();
  86. let disk_plugin = Arc::new(
  87. RocksDiskPlugin::new(uid, kv_db).map_err(|err| FlowyError::internal().context(err))?,
  88. );
  89. collab.add_plugin(disk_plugin);
  90. collab.initial();
  91. Ok(collab)
  92. }
  93. }