mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
mv websocket to flowy-net crate
This commit is contained in:
@ -11,6 +11,7 @@ members = [
|
||||
"flowy-core",
|
||||
"dart-notify",
|
||||
"flowy-document",
|
||||
"flowy-error",
|
||||
]
|
||||
|
||||
exclude = ["../backend"]
|
||||
|
@ -52,7 +52,7 @@ color-eyre = { version = "0.5", default-features = false }
|
||||
criterion = "0.3"
|
||||
rand = "0.7.3"
|
||||
env_logger = "0.8.2"
|
||||
flowy-user = { path = "../flowy-user", features = ["ws_mock"] }
|
||||
flowy-net = { path = "../flowy-net", features = ["ws_mock"] }
|
||||
|
||||
[features]
|
||||
http_server = []
|
||||
|
@ -63,7 +63,7 @@ impl RevisionCache {
|
||||
}
|
||||
let record = RevisionRecord {
|
||||
revision,
|
||||
state: RevState::Local,
|
||||
state: RevState::StateLocal,
|
||||
};
|
||||
self.memory_cache.add_revision(record).await?;
|
||||
self.save_revisions().await;
|
||||
@ -77,7 +77,7 @@ impl RevisionCache {
|
||||
}
|
||||
let record = RevisionRecord {
|
||||
revision,
|
||||
state: RevState::Local,
|
||||
state: RevState::StateLocal,
|
||||
};
|
||||
self.memory_cache.add_revision(record).await?;
|
||||
self.save_revisions().await;
|
||||
|
@ -35,7 +35,7 @@ impl RevisionMemoryCache {
|
||||
}
|
||||
|
||||
match record.state {
|
||||
RevState::Local => {
|
||||
RevState::StateLocal => {
|
||||
tracing::debug!("{}:add revision {}", record.revision.doc_id, record.revision.rev_id);
|
||||
self.local_revs.write().await.push_back(record.revision.rev_id);
|
||||
},
|
||||
|
@ -13,7 +13,7 @@ pub(crate) trait WsDocumentHandler: Send + Sync {
|
||||
pub type WsStateReceiver = tokio::sync::broadcast::Receiver<WsConnectState>;
|
||||
pub trait DocumentWebSocket: Send + Sync {
|
||||
fn send(&self, data: WsDocumentData) -> Result<(), DocError>;
|
||||
fn state_notify(&self) -> WsStateReceiver;
|
||||
fn subscribe_state_changed(&self) -> WsStateReceiver;
|
||||
}
|
||||
|
||||
pub struct WsDocumentManager {
|
||||
@ -56,7 +56,7 @@ impl WsDocumentManager {
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(ws, handlers))]
|
||||
fn listen_ws_state_changed(ws: Arc<dyn DocumentWebSocket>, handlers: Arc<DashMap<String, Arc<dyn WsDocumentHandler>>>) {
|
||||
let mut notify = ws.state_notify();
|
||||
let mut notify = ws.subscribe_state_changed();
|
||||
tokio::spawn(async move {
|
||||
while let Ok(state) = notify.recv().await {
|
||||
handlers.iter().for_each(|handle| {
|
||||
|
@ -49,7 +49,7 @@ impl_sql_integer_expression!(RevTableState);
|
||||
impl std::convert::From<RevTableState> for RevState {
|
||||
fn from(s: RevTableState) -> Self {
|
||||
match s {
|
||||
RevTableState::Local => RevState::Local,
|
||||
RevTableState::Local => RevState::StateLocal,
|
||||
RevTableState::Acked => RevState::Acked,
|
||||
}
|
||||
}
|
||||
@ -58,7 +58,7 @@ impl std::convert::From<RevTableState> for RevState {
|
||||
impl std::convert::From<RevState> for RevTableState {
|
||||
fn from(s: RevState) -> Self {
|
||||
match s {
|
||||
RevState::Local => RevTableState::Local,
|
||||
RevState::StateLocal => RevTableState::Local,
|
||||
RevState::Acked => RevTableState::Acked,
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ async fn doc_rev_state_test1() {
|
||||
let scripts = vec![
|
||||
InsertText("123", 0),
|
||||
AssertCurrentRevId(1),
|
||||
AssertRevisionState(1, RevState::Local),
|
||||
AssertRevisionState(1, RevState::StateLocal),
|
||||
SimulateAckedMessage(1),
|
||||
AssertRevisionState(1, RevState::Acked),
|
||||
AssertNextSendingRevision(None),
|
||||
@ -22,9 +22,9 @@ async fn doc_rev_state_test2() {
|
||||
InsertText("2", 1),
|
||||
InsertText("3", 2),
|
||||
AssertCurrentRevId(3),
|
||||
AssertRevisionState(1, RevState::Local),
|
||||
AssertRevisionState(2, RevState::Local),
|
||||
AssertRevisionState(3, RevState::Local),
|
||||
AssertRevisionState(1, RevState::StateLocal),
|
||||
AssertRevisionState(2, RevState::StateLocal),
|
||||
AssertRevisionState(3, RevState::StateLocal),
|
||||
SimulateAckedMessage(1),
|
||||
AssertRevisionState(1, RevState::Acked),
|
||||
AssertNextSendingRevision(Some(2)),
|
||||
@ -32,7 +32,7 @@ async fn doc_rev_state_test2() {
|
||||
AssertRevisionState(2, RevState::Acked),
|
||||
//
|
||||
AssertNextSendingRevision(Some(3)),
|
||||
AssertRevisionState(3, RevState::Local),
|
||||
AssertRevisionState(3, RevState::StateLocal),
|
||||
AssertJson(r#"[{"insert":"123\n"}]"#),
|
||||
];
|
||||
EditorTest::new().await.run_scripts(scripts).await;
|
||||
|
13
frontend/rust-lib/flowy-error/Cargo.toml
Normal file
13
frontend/rust-lib/flowy-error/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "flowy-error"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
flowy-derive = { path = "../../../shared-lib/flowy-derive" }
|
||||
derive_more = {version = "0.99", features = ["display"]}
|
||||
lib-dispatch = { path = "../lib-dispatch" }
|
||||
protobuf = {version = "2.20.0"}
|
||||
bytes = "1.0"
|
3
frontend/rust-lib/flowy-error/Flowy.toml
Normal file
3
frontend/rust-lib/flowy-error/Flowy.toml
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
proto_crates = ["src/errors.rs",]
|
||||
event_files = []
|
84
frontend/rust-lib/flowy-error/src/errors.rs
Normal file
84
frontend/rust-lib/flowy-error/src/errors.rs
Normal file
@ -0,0 +1,84 @@
|
||||
use crate::protobuf::ErrorCode as ProtoBufErrorCode;
|
||||
use bytes::Bytes;
|
||||
use derive_more::Display;
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
use lib_dispatch::prelude::{EventResponse, ResponseBuilder};
|
||||
use protobuf::ProtobufEnum;
|
||||
use std::{
|
||||
convert::{TryFrom, TryInto},
|
||||
fmt::Debug,
|
||||
};
|
||||
|
||||
#[derive(Debug, Default, Clone, ProtoBuf)]
|
||||
pub struct FlowyError {
|
||||
#[pb(index = 1)]
|
||||
pub code: i32,
|
||||
|
||||
#[pb(index = 2)]
|
||||
pub msg: String,
|
||||
}
|
||||
|
||||
macro_rules! static_any_error {
|
||||
($name:ident, $code:expr) => {
|
||||
#[allow(non_snake_case, missing_docs)]
|
||||
pub fn $name() -> FlowyError { $code.into() }
|
||||
};
|
||||
}
|
||||
|
||||
impl FlowyError {
|
||||
pub fn new(code: ErrorCode, msg: &str) -> Self {
|
||||
Self {
|
||||
code: code.value(),
|
||||
msg: msg.to_owned(),
|
||||
}
|
||||
}
|
||||
pub fn context<T: Debug>(mut self, error: T) -> Self {
|
||||
self.msg = format!("{:?}", error);
|
||||
self
|
||||
}
|
||||
|
||||
static_any_error!(internal, ErrorCode::Internal);
|
||||
}
|
||||
|
||||
impl std::convert::From<ErrorCode> for FlowyError {
|
||||
fn from(code: ErrorCode) -> Self {
|
||||
FlowyError {
|
||||
code: code.value(),
|
||||
msg: format!("{}", code),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, ProtoBuf_Enum, Display, PartialEq, Eq)]
|
||||
pub enum ErrorCode {
|
||||
#[display(fmt = "Internal error")]
|
||||
Internal = 0,
|
||||
}
|
||||
|
||||
impl ErrorCode {
|
||||
pub fn value(&self) -> i32 {
|
||||
let code: ProtoBufErrorCode = self.clone().try_into().unwrap();
|
||||
code.value()
|
||||
}
|
||||
|
||||
pub fn from_i32(value: i32) -> Self {
|
||||
match ProtoBufErrorCode::from_i32(value) {
|
||||
None => ErrorCode::Internal,
|
||||
Some(code) => ErrorCode::try_from(&code).unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn internal_error<T>(e: T) -> FlowyError
|
||||
where
|
||||
T: std::fmt::Debug,
|
||||
{
|
||||
FlowyError::internal().context(e)
|
||||
}
|
||||
|
||||
impl lib_dispatch::Error for FlowyError {
|
||||
fn as_response(&self) -> EventResponse {
|
||||
let bytes: Bytes = self.clone().try_into().unwrap();
|
||||
ResponseBuilder::Err().data(bytes).build()
|
||||
}
|
||||
}
|
4
frontend/rust-lib/flowy-error/src/lib.rs
Normal file
4
frontend/rust-lib/flowy-error/src/lib.rs
Normal file
@ -0,0 +1,4 @@
|
||||
mod errors;
|
||||
pub mod protobuf;
|
||||
|
||||
pub use errors::*;
|
4
frontend/rust-lib/flowy-error/src/protobuf/mod.rs
Normal file
4
frontend/rust-lib/flowy-error/src/protobuf/mod.rs
Normal file
@ -0,0 +1,4 @@
|
||||
#![cfg_attr(rustfmt, rustfmt::skip)]
|
||||
// Auto-generated, do not edit
|
||||
mod model;
|
||||
pub use model::*;
|
293
frontend/rust-lib/flowy-error/src/protobuf/model/errors.rs
Normal file
293
frontend/rust-lib/flowy-error/src/protobuf/model/errors.rs
Normal file
@ -0,0 +1,293 @@
|
||||
// This file is generated by rust-protobuf 2.22.1. Do not edit
|
||||
// @generated
|
||||
|
||||
// https://github.com/rust-lang/rust-clippy/issues/702
|
||||
#![allow(unknown_lints)]
|
||||
#![allow(clippy::all)]
|
||||
|
||||
#![allow(unused_attributes)]
|
||||
#![cfg_attr(rustfmt, rustfmt::skip)]
|
||||
|
||||
#![allow(box_pointers)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(missing_docs)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(trivial_casts)]
|
||||
#![allow(unused_imports)]
|
||||
#![allow(unused_results)]
|
||||
//! Generated file from `errors.proto`
|
||||
|
||||
/// Generated files are compatible only with the same version
|
||||
/// of protobuf runtime.
|
||||
// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_22_1;
|
||||
|
||||
#[derive(PartialEq,Clone,Default)]
|
||||
pub struct FlowyError {
|
||||
// message fields
|
||||
pub code: i32,
|
||||
pub msg: ::std::string::String,
|
||||
// special fields
|
||||
pub unknown_fields: ::protobuf::UnknownFields,
|
||||
pub cached_size: ::protobuf::CachedSize,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a FlowyError {
|
||||
fn default() -> &'a FlowyError {
|
||||
<FlowyError as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl FlowyError {
|
||||
pub fn new() -> FlowyError {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
// int32 code = 1;
|
||||
|
||||
|
||||
pub fn get_code(&self) -> i32 {
|
||||
self.code
|
||||
}
|
||||
pub fn clear_code(&mut self) {
|
||||
self.code = 0;
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_code(&mut self, v: i32) {
|
||||
self.code = v;
|
||||
}
|
||||
|
||||
// string msg = 2;
|
||||
|
||||
|
||||
pub fn get_msg(&self) -> &str {
|
||||
&self.msg
|
||||
}
|
||||
pub fn clear_msg(&mut self) {
|
||||
self.msg.clear();
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_msg(&mut self, v: ::std::string::String) {
|
||||
self.msg = v;
|
||||
}
|
||||
|
||||
// Mutable pointer to the field.
|
||||
// If field is not initialized, it is initialized with default value first.
|
||||
pub fn mut_msg(&mut self) -> &mut ::std::string::String {
|
||||
&mut self.msg
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_msg(&mut self) -> ::std::string::String {
|
||||
::std::mem::replace(&mut self.msg, ::std::string::String::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for FlowyError {
|
||||
fn is_initialized(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> {
|
||||
while !is.eof()? {
|
||||
let (field_number, wire_type) = is.read_tag_unpack()?;
|
||||
match field_number {
|
||||
1 => {
|
||||
if wire_type != ::protobuf::wire_format::WireTypeVarint {
|
||||
return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
|
||||
}
|
||||
let tmp = is.read_int32()?;
|
||||
self.code = tmp;
|
||||
},
|
||||
2 => {
|
||||
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.msg)?;
|
||||
},
|
||||
_ => {
|
||||
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
|
||||
},
|
||||
};
|
||||
}
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
|
||||
// Compute sizes of nested messages
|
||||
#[allow(unused_variables)]
|
||||
fn compute_size(&self) -> u32 {
|
||||
let mut my_size = 0;
|
||||
if self.code != 0 {
|
||||
my_size += ::protobuf::rt::value_size(1, self.code, ::protobuf::wire_format::WireTypeVarint);
|
||||
}
|
||||
if !self.msg.is_empty() {
|
||||
my_size += ::protobuf::rt::string_size(2, &self.msg);
|
||||
}
|
||||
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
|
||||
self.cached_size.set(my_size);
|
||||
my_size
|
||||
}
|
||||
|
||||
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> {
|
||||
if self.code != 0 {
|
||||
os.write_int32(1, self.code)?;
|
||||
}
|
||||
if !self.msg.is_empty() {
|
||||
os.write_string(2, &self.msg)?;
|
||||
}
|
||||
os.write_unknown_fields(self.get_unknown_fields())?;
|
||||
::std::result::Result::Ok(())
|
||||
}
|
||||
|
||||
fn get_cached_size(&self) -> u32 {
|
||||
self.cached_size.get()
|
||||
}
|
||||
|
||||
fn get_unknown_fields(&self) -> &::protobuf::UnknownFields {
|
||||
&self.unknown_fields
|
||||
}
|
||||
|
||||
fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields {
|
||||
&mut self.unknown_fields
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn (::std::any::Any) {
|
||||
self as &dyn (::std::any::Any)
|
||||
}
|
||||
fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) {
|
||||
self as &mut dyn (::std::any::Any)
|
||||
}
|
||||
fn into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)> {
|
||||
self
|
||||
}
|
||||
|
||||
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
Self::descriptor_static()
|
||||
}
|
||||
|
||||
fn new() -> FlowyError {
|
||||
FlowyError::new()
|
||||
}
|
||||
|
||||
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||
static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT;
|
||||
descriptor.get(|| {
|
||||
let mut fields = ::std::vec::Vec::new();
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt32>(
|
||||
"code",
|
||||
|m: &FlowyError| { &m.code },
|
||||
|m: &mut FlowyError| { &mut m.code },
|
||||
));
|
||||
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||
"msg",
|
||||
|m: &FlowyError| { &m.msg },
|
||||
|m: &mut FlowyError| { &mut m.msg },
|
||||
));
|
||||
::protobuf::reflect::MessageDescriptor::new_pb_name::<FlowyError>(
|
||||
"FlowyError",
|
||||
fields,
|
||||
file_descriptor_proto()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static FlowyError {
|
||||
static instance: ::protobuf::rt::LazyV2<FlowyError> = ::protobuf::rt::LazyV2::INIT;
|
||||
instance.get(FlowyError::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Clear for FlowyError {
|
||||
fn clear(&mut self) {
|
||||
self.code = 0;
|
||||
self.msg.clear();
|
||||
self.unknown_fields.clear();
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Debug for FlowyError {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
::protobuf::text_format::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for FlowyError {
|
||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
||||
::protobuf::reflect::ReflectValueRef::Message(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone,PartialEq,Eq,Debug,Hash)]
|
||||
pub enum ErrorCode {
|
||||
Internal = 0,
|
||||
}
|
||||
|
||||
impl ::protobuf::ProtobufEnum for ErrorCode {
|
||||
fn value(&self) -> i32 {
|
||||
*self as i32
|
||||
}
|
||||
|
||||
fn from_i32(value: i32) -> ::std::option::Option<ErrorCode> {
|
||||
match value {
|
||||
0 => ::std::option::Option::Some(ErrorCode::Internal),
|
||||
_ => ::std::option::Option::None
|
||||
}
|
||||
}
|
||||
|
||||
fn values() -> &'static [Self] {
|
||||
static values: &'static [ErrorCode] = &[
|
||||
ErrorCode::Internal,
|
||||
];
|
||||
values
|
||||
}
|
||||
|
||||
fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
|
||||
static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT;
|
||||
descriptor.get(|| {
|
||||
::protobuf::reflect::EnumDescriptor::new_pb_name::<ErrorCode>("ErrorCode", file_descriptor_proto())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::marker::Copy for ErrorCode {
|
||||
}
|
||||
|
||||
impl ::std::default::Default for ErrorCode {
|
||||
fn default() -> Self {
|
||||
ErrorCode::Internal
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for ErrorCode {
|
||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
||||
::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self))
|
||||
}
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\x0cerrors.proto\"2\n\nFlowyError\x12\x12\n\x04code\x18\x01\x20\x01(\
|
||||
\x05R\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\tR\x03msg*\x19\n\tErrorC\
|
||||
ode\x12\x0c\n\x08Internal\x10\0J\xd9\x01\n\x06\x12\x04\0\0\x08\x01\n\x08\
|
||||
\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\
|
||||
\x03\x04\0\x01\x12\x03\x02\x08\x12\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\
|
||||
\x04\x13\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\x04\t\n\x0c\n\x05\x04\0\
|
||||
\x02\0\x01\x12\x03\x03\n\x0e\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x11\
|
||||
\x12\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x13\n\x0c\n\x05\x04\0\x02\
|
||||
\x01\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0b\
|
||||
\x0e\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x11\x12\n\n\n\x02\x05\0\
|
||||
\x12\x04\x06\0\x08\x01\n\n\n\x03\x05\0\x01\x12\x03\x06\x05\x0e\n\x0b\n\
|
||||
\x04\x05\0\x02\0\x12\x03\x07\x04\x11\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\
|
||||
\x07\x04\x0c\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x07\x0f\x10b\x06proto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
||||
fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
|
||||
::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap()
|
||||
}
|
||||
|
||||
pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
|
||||
file_descriptor_proto_lazy.get(|| {
|
||||
parse_descriptor_proto()
|
||||
})
|
||||
}
|
5
frontend/rust-lib/flowy-error/src/protobuf/model/mod.rs
Normal file
5
frontend/rust-lib/flowy-error/src/protobuf/model/mod.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#![cfg_attr(rustfmt, rustfmt::skip)]
|
||||
// Auto-generated, do not edit
|
||||
|
||||
mod errors;
|
||||
pub use errors::*;
|
@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
message FlowyError {
|
||||
int32 code = 1;
|
||||
string msg = 2;
|
||||
}
|
||||
enum ErrorCode {
|
||||
Internal = 0;
|
||||
}
|
@ -6,6 +6,23 @@ edition = "2018"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
lib-dispatch = { path = "../lib-dispatch" }
|
||||
flowy-error = { path = "../flowy-error" }
|
||||
flowy-derive = { path = "../../../shared-lib/flowy-derive" }
|
||||
lib-infra = { path = "../../../shared-lib/lib-infra" }
|
||||
lib-ws = { path = "../../../shared-lib/lib-ws" }
|
||||
protobuf = {version = "2.18.0"}
|
||||
bytes = { version = "1.0" }
|
||||
bytes = { version = "1.0" }
|
||||
anyhow = "1.0"
|
||||
tokio = {version = "1", features = ["sync"]}
|
||||
parking_lot = "0.11"
|
||||
strum = "0.21"
|
||||
strum_macros = "0.21"
|
||||
tracing = { version = "0.1", features = ["log"] }
|
||||
|
||||
flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration", optional = true}
|
||||
lazy_static = {version = "1.4.0", optional = true}
|
||||
dashmap = {version = "4.0", optional = true}
|
||||
|
||||
[features]
|
||||
ws_mock = ["flowy-collaboration", "lazy_static", "dashmap"]
|
@ -1,2 +1,2 @@
|
||||
proto_crates = ["src/entities"]
|
||||
event_files = []
|
||||
proto_crates = ["src/event.rs", "src/entities"]
|
||||
event_files = ["src/event.rs"]
|
9
frontend/rust-lib/flowy-net/src/event.rs
Normal file
9
frontend/rust-lib/flowy-net/src/event.rs
Normal file
@ -0,0 +1,9 @@
|
||||
use flowy_derive::{Flowy_Event, ProtoBuf_Enum};
|
||||
use strum_macros::Display;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
|
||||
#[event_err = "FlowyError"]
|
||||
pub enum NetworkEvent {
|
||||
#[event(input = "NetworkState")]
|
||||
UpdateNetworkType = 0,
|
||||
}
|
12
frontend/rust-lib/flowy-net/src/handlers/mod.rs
Normal file
12
frontend/rust-lib/flowy-net/src/handlers/mod.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use crate::{entities::NetworkState, services::ws::WsManager};
|
||||
use bytes::Bytes;
|
||||
use flowy_error::FlowyError;
|
||||
use lib_dispatch::prelude::{Data, Unit};
|
||||
use std::sync::Arc;
|
||||
|
||||
#[tracing::instrument(skip(data, ws_manager))]
|
||||
pub async fn update_network_ty(data: Data<NetworkState>, ws_manager: Unit<Arc<WsManager>>) -> Result<(), FlowyError> {
|
||||
let network_state = data.into_inner();
|
||||
ws_manager.update_network_type(&network_state.ty);
|
||||
Ok(())
|
||||
}
|
@ -1,2 +1,6 @@
|
||||
pub mod entities;
|
||||
mod event;
|
||||
mod handlers;
|
||||
pub mod module;
|
||||
pub mod protobuf;
|
||||
pub mod services;
|
||||
|
10
frontend/rust-lib/flowy-net/src/module.rs
Normal file
10
frontend/rust-lib/flowy-net/src/module.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use crate::{event::NetworkEvent, handlers::*, services::ws::WsManager};
|
||||
use lib_dispatch::prelude::*;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub fn create(ws_manager: Arc<WsManager>) -> Module {
|
||||
Module::new()
|
||||
.name("Flowy-Network")
|
||||
.data(ws_manager.clone())
|
||||
.event(NetworkEvent::UpdateNetworkType, update_network_ty)
|
||||
}
|
92
frontend/rust-lib/flowy-net/src/protobuf/model/event.rs
Normal file
92
frontend/rust-lib/flowy-net/src/protobuf/model/event.rs
Normal file
@ -0,0 +1,92 @@
|
||||
// This file is generated by rust-protobuf 2.22.1. Do not edit
|
||||
// @generated
|
||||
|
||||
// https://github.com/rust-lang/rust-clippy/issues/702
|
||||
#![allow(unknown_lints)]
|
||||
#![allow(clippy::all)]
|
||||
|
||||
#![allow(unused_attributes)]
|
||||
#![cfg_attr(rustfmt, rustfmt::skip)]
|
||||
|
||||
#![allow(box_pointers)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(missing_docs)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(trivial_casts)]
|
||||
#![allow(unused_imports)]
|
||||
#![allow(unused_results)]
|
||||
//! Generated file from `event.proto`
|
||||
|
||||
/// Generated files are compatible only with the same version
|
||||
/// of protobuf runtime.
|
||||
// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_22_1;
|
||||
|
||||
#[derive(Clone,PartialEq,Eq,Debug,Hash)]
|
||||
pub enum NetworkEvent {
|
||||
UpdateNetworkType = 0,
|
||||
}
|
||||
|
||||
impl ::protobuf::ProtobufEnum for NetworkEvent {
|
||||
fn value(&self) -> i32 {
|
||||
*self as i32
|
||||
}
|
||||
|
||||
fn from_i32(value: i32) -> ::std::option::Option<NetworkEvent> {
|
||||
match value {
|
||||
0 => ::std::option::Option::Some(NetworkEvent::UpdateNetworkType),
|
||||
_ => ::std::option::Option::None
|
||||
}
|
||||
}
|
||||
|
||||
fn values() -> &'static [Self] {
|
||||
static values: &'static [NetworkEvent] = &[
|
||||
NetworkEvent::UpdateNetworkType,
|
||||
];
|
||||
values
|
||||
}
|
||||
|
||||
fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor {
|
||||
static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT;
|
||||
descriptor.get(|| {
|
||||
::protobuf::reflect::EnumDescriptor::new_pb_name::<NetworkEvent>("NetworkEvent", file_descriptor_proto())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::marker::Copy for NetworkEvent {
|
||||
}
|
||||
|
||||
impl ::std::default::Default for NetworkEvent {
|
||||
fn default() -> Self {
|
||||
NetworkEvent::UpdateNetworkType
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for NetworkEvent {
|
||||
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
|
||||
::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self))
|
||||
}
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\x0bevent.proto*%\n\x0cNetworkEvent\x12\x15\n\x11UpdateNetworkType\x10\
|
||||
\0JS\n\x06\x12\x04\0\0\x04\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\
|
||||
\x05\0\x12\x04\x02\0\x04\x01\n\n\n\x03\x05\0\x01\x12\x03\x02\x05\x11\n\
|
||||
\x0b\n\x04\x05\0\x02\0\x12\x03\x03\x04\x1a\n\x0c\n\x05\x05\0\x02\0\x01\
|
||||
\x12\x03\x03\x04\x15\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x03\x18\x19b\
|
||||
\x06proto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
||||
fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto {
|
||||
::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap()
|
||||
}
|
||||
|
||||
pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto {
|
||||
file_descriptor_proto_lazy.get(|| {
|
||||
parse_descriptor_proto()
|
||||
})
|
||||
}
|
@ -3,3 +3,6 @@
|
||||
|
||||
mod network_state;
|
||||
pub use network_state::*;
|
||||
|
||||
mod event;
|
||||
pub use event::*;
|
||||
|
@ -0,0 +1,5 @@
|
||||
syntax = "proto3";
|
||||
|
||||
enum NetworkEvent {
|
||||
UpdateNetworkType = 0;
|
||||
}
|
3
frontend/rust-lib/flowy-net/src/services/mock/mod.rs
Normal file
3
frontend/rust-lib/flowy-net/src/services/mock/mod.rs
Normal file
@ -0,0 +1,3 @@
|
||||
mod ws_mock;
|
||||
|
||||
pub use ws_mock::*;
|
@ -1,23 +1,19 @@
|
||||
use crate::{
|
||||
errors::UserError,
|
||||
services::user::ws_manager::{FlowyWebSocket, FlowyWsSender},
|
||||
};
|
||||
use crate::services::ws::{FlowyError, FlowyWebSocket, FlowyWsSender, WsConnectState, WsMessage, WsMessageHandler};
|
||||
use bytes::Bytes;
|
||||
use dashmap::DashMap;
|
||||
use flowy_collaboration::{
|
||||
core::sync::{ServerDocManager, ServerDocPersistence},
|
||||
core::sync::{RevisionUser, ServerDocManager, ServerDocPersistence, SyncResponse},
|
||||
entities::{
|
||||
doc::Doc,
|
||||
ws::{WsDataType, WsDocumentData},
|
||||
},
|
||||
errors::CollaborateError,
|
||||
Revision,
|
||||
RichTextDelta,
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use lib_infra::future::{FutureResult, FutureResultSend};
|
||||
use lib_ot::{revision::Revision, rich_text::RichTextDelta};
|
||||
use lib_ws::{WsConnectState, WsMessage, WsMessageHandler, WsModule};
|
||||
|
||||
use flowy_collaboration::core::sync::{RevisionUser, SyncResponse};
|
||||
use lib_ws::WsModule;
|
||||
use std::{
|
||||
convert::{TryFrom, TryInto},
|
||||
sync::Arc,
|
||||
@ -47,7 +43,7 @@ impl MockWebSocket {
|
||||
}
|
||||
|
||||
impl FlowyWebSocket for Arc<MockWebSocket> {
|
||||
fn start_connect(&self, _addr: String) -> FutureResult<(), UserError> {
|
||||
fn start_connect(&self, _addr: String) -> FutureResult<(), FlowyError> {
|
||||
let mut ws_receiver = self.ws_sender.subscribe();
|
||||
let cloned_ws = self.clone();
|
||||
tokio::spawn(async move {
|
||||
@ -56,7 +52,7 @@ impl FlowyWebSocket for Arc<MockWebSocket> {
|
||||
let mut rx = DOC_SERVER.handle_ws_data(ws_data).await;
|
||||
let new_ws_message = rx.recv().await.unwrap();
|
||||
match cloned_ws.handlers.get(&new_ws_message.module) {
|
||||
None => log::error!("Can't find any handler for message: {:?}", new_ws_message),
|
||||
None => tracing::error!("Can't find any handler for message: {:?}", new_ws_message),
|
||||
Some(handler) => handler.receive_message(new_ws_message.clone()),
|
||||
}
|
||||
}
|
||||
@ -67,18 +63,18 @@ impl FlowyWebSocket for Arc<MockWebSocket> {
|
||||
|
||||
fn conn_state_subscribe(&self) -> Receiver<WsConnectState> { self.state_sender.subscribe() }
|
||||
|
||||
fn reconnect(&self, _count: usize) -> FutureResult<(), UserError> { FutureResult::new(async { Ok(()) }) }
|
||||
fn reconnect(&self, _count: usize) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) }
|
||||
|
||||
fn add_handler(&self, handler: Arc<dyn WsMessageHandler>) -> Result<(), UserError> {
|
||||
fn add_handler(&self, handler: Arc<dyn WsMessageHandler>) -> Result<(), FlowyError> {
|
||||
let source = handler.source();
|
||||
if self.handlers.contains_key(&source) {
|
||||
log::error!("WsSource's {:?} is already registered", source);
|
||||
tracing::error!("WsSource's {:?} is already registered", source);
|
||||
}
|
||||
self.handlers.insert(source, handler);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn ws_sender(&self) -> Result<Arc<dyn FlowyWsSender>, UserError> { Ok(Arc::new(self.ws_sender.clone())) }
|
||||
fn ws_sender(&self) -> Result<Arc<dyn FlowyWsSender>, FlowyError> { Ok(Arc::new(self.ws_sender.clone())) }
|
||||
}
|
||||
|
||||
lazy_static! {
|
4
frontend/rust-lib/flowy-net/src/services/mod.rs
Normal file
4
frontend/rust-lib/flowy-net/src/services/mod.rs
Normal file
@ -0,0 +1,4 @@
|
||||
pub mod ws;
|
||||
|
||||
#[cfg(feature = "ws_mock")]
|
||||
mod mock;
|
18
frontend/rust-lib/flowy-net/src/services/ws/conn.rs
Normal file
18
frontend/rust-lib/flowy-net/src/services/ws/conn.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use lib_infra::future::FutureResult;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::broadcast;
|
||||
|
||||
pub use flowy_error::FlowyError;
|
||||
pub use lib_ws::{WsConnectState, WsMessage, WsMessageHandler};
|
||||
|
||||
pub trait FlowyWebSocket: Send + Sync {
|
||||
fn start_connect(&self, addr: String) -> FutureResult<(), FlowyError>;
|
||||
fn conn_state_subscribe(&self) -> broadcast::Receiver<WsConnectState>;
|
||||
fn reconnect(&self, count: usize) -> FutureResult<(), FlowyError>;
|
||||
fn add_handler(&self, handler: Arc<dyn WsMessageHandler>) -> Result<(), FlowyError>;
|
||||
fn ws_sender(&self) -> Result<Arc<dyn FlowyWsSender>, FlowyError>;
|
||||
}
|
||||
|
||||
pub trait FlowyWsSender: Send + Sync {
|
||||
fn send(&self, msg: WsMessage) -> Result<(), FlowyError>;
|
||||
}
|
@ -1,42 +1,52 @@
|
||||
use crate::errors::UserError;
|
||||
|
||||
use flowy_net::entities::NetworkType;
|
||||
use crate::{
|
||||
entities::NetworkType,
|
||||
services::ws::{local_web_socket, FlowyWebSocket, FlowyWsSender},
|
||||
};
|
||||
use flowy_error::{internal_error, FlowyError};
|
||||
use lib_infra::future::FutureResult;
|
||||
use lib_ws::{WsConnectState, WsController, WsMessage, WsMessageHandler, WsSender};
|
||||
use parking_lot::RwLock;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{broadcast, broadcast::Receiver};
|
||||
|
||||
pub trait FlowyWebSocket: Send + Sync {
|
||||
fn start_connect(&self, addr: String) -> FutureResult<(), UserError>;
|
||||
fn conn_state_subscribe(&self) -> broadcast::Receiver<WsConnectState>;
|
||||
fn reconnect(&self, count: usize) -> FutureResult<(), UserError>;
|
||||
fn add_handler(&self, handler: Arc<dyn WsMessageHandler>) -> Result<(), UserError>;
|
||||
fn ws_sender(&self) -> Result<Arc<dyn FlowyWsSender>, UserError>;
|
||||
}
|
||||
|
||||
pub trait FlowyWsSender: Send + Sync {
|
||||
fn send(&self, msg: WsMessage) -> Result<(), UserError>;
|
||||
}
|
||||
|
||||
pub struct WsManager {
|
||||
inner: Arc<dyn FlowyWebSocket>,
|
||||
connect_type: RwLock<NetworkType>,
|
||||
status_notifier: broadcast::Sender<NetworkType>,
|
||||
addr: String,
|
||||
}
|
||||
|
||||
impl WsManager {
|
||||
pub fn new() -> Self { WsManager::default() }
|
||||
pub fn new(addr: String) -> Self {
|
||||
let ws: Arc<dyn FlowyWebSocket> = if cfg!(feature = "http_server") {
|
||||
Arc::new(Arc::new(WsController::new()))
|
||||
} else {
|
||||
local_web_socket()
|
||||
};
|
||||
|
||||
pub async fn start(&self, addr: String) -> Result<(), UserError> {
|
||||
let (status_notifier, _) = broadcast::channel(10);
|
||||
WsManager {
|
||||
inner: ws,
|
||||
connect_type: RwLock::new(NetworkType::default()),
|
||||
status_notifier,
|
||||
addr,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn start(&self, token: String) -> Result<(), FlowyError> {
|
||||
let addr = format!("{}/{}", self.addr, token);
|
||||
self.listen_on_websocket();
|
||||
let _ = self.inner.start_connect(addr).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn update_network_type(&self, new_type: &NetworkType) {
|
||||
tracing::debug!("Network new state: {:?}", new_type);
|
||||
let old_type = self.connect_type.read().clone();
|
||||
let _ = self.status_notifier.send(new_type.clone());
|
||||
|
||||
if &old_type != new_type {
|
||||
log::debug!("Connect type switch from {:?} to {:?}", old_type, new_type);
|
||||
tracing::debug!("Connect type switch from {:?} to {:?}", old_type, new_type);
|
||||
match (old_type.is_connect(), new_type.is_connect()) {
|
||||
(false, true) => {
|
||||
let ws_controller = self.inner.clone();
|
||||
@ -69,7 +79,7 @@ impl WsManager {
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("Websocket state notify error: {:?}", e);
|
||||
tracing::error!("Websocket state notify error: {:?}", e);
|
||||
break;
|
||||
},
|
||||
}
|
||||
@ -77,76 +87,60 @@ impl WsManager {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn state_subscribe(&self) -> broadcast::Receiver<WsConnectState> { self.inner.conn_state_subscribe() }
|
||||
pub fn subscribe_websocket_state(&self) -> broadcast::Receiver<WsConnectState> { self.inner.conn_state_subscribe() }
|
||||
|
||||
pub fn add_handler(&self, handler: Arc<dyn WsMessageHandler>) -> Result<(), UserError> {
|
||||
pub fn subscribe_network_ty(&self) -> broadcast::Receiver<NetworkType> { self.status_notifier.subscribe() }
|
||||
|
||||
pub fn add_handler(&self, handler: Arc<dyn WsMessageHandler>) -> Result<(), FlowyError> {
|
||||
let _ = self.inner.add_handler(handler)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn ws_sender(&self) -> Result<Arc<dyn FlowyWsSender>, UserError> {
|
||||
//
|
||||
self.inner.ws_sender()
|
||||
}
|
||||
pub fn ws_sender(&self) -> Result<Arc<dyn FlowyWsSender>, FlowyError> { self.inner.ws_sender() }
|
||||
}
|
||||
|
||||
async fn retry_connect(ws: Arc<dyn FlowyWebSocket>, count: usize) {
|
||||
match ws.reconnect(count).await {
|
||||
Ok(_) => {},
|
||||
Err(e) => {
|
||||
log::error!("websocket connect failed: {:?}", e);
|
||||
tracing::error!("websocket connect failed: {:?}", e);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
impl std::default::Default for WsManager {
|
||||
fn default() -> Self {
|
||||
let ws: Arc<dyn FlowyWebSocket> = if cfg!(feature = "http_server") {
|
||||
Arc::new(Arc::new(WsController::new()))
|
||||
} else {
|
||||
crate::services::server::local_web_socket()
|
||||
};
|
||||
|
||||
WsManager {
|
||||
inner: ws,
|
||||
connect_type: RwLock::new(NetworkType::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FlowyWebSocket for Arc<WsController> {
|
||||
fn start_connect(&self, addr: String) -> FutureResult<(), UserError> {
|
||||
fn start_connect(&self, addr: String) -> FutureResult<(), FlowyError> {
|
||||
let cloned_ws = self.clone();
|
||||
FutureResult::new(async move {
|
||||
let _ = cloned_ws.start(addr).await?;
|
||||
let _ = cloned_ws.start(addr).await.map_err(internal_error)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn conn_state_subscribe(&self) -> Receiver<WsConnectState> { self.state_subscribe() }
|
||||
|
||||
fn reconnect(&self, count: usize) -> FutureResult<(), UserError> {
|
||||
fn reconnect(&self, count: usize) -> FutureResult<(), FlowyError> {
|
||||
let cloned_ws = self.clone();
|
||||
FutureResult::new(async move {
|
||||
let _ = cloned_ws.retry(count).await?;
|
||||
let _ = cloned_ws.retry(count).await.map_err(internal_error)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn add_handler(&self, handler: Arc<dyn WsMessageHandler>) -> Result<(), UserError> {
|
||||
fn add_handler(&self, handler: Arc<dyn WsMessageHandler>) -> Result<(), FlowyError> {
|
||||
let _ = self.add_handler(handler)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn ws_sender(&self) -> Result<Arc<dyn FlowyWsSender>, UserError> {
|
||||
let sender = self.sender()?;
|
||||
fn ws_sender(&self) -> Result<Arc<dyn FlowyWsSender>, FlowyError> {
|
||||
let sender = self.sender().map_err(internal_error)?;
|
||||
Ok(sender)
|
||||
}
|
||||
}
|
||||
|
||||
impl FlowyWsSender for WsSender {
|
||||
fn send(&self, msg: WsMessage) -> Result<(), UserError> {
|
||||
let _ = self.send_msg(msg)?;
|
||||
fn send(&self, msg: WsMessage) -> Result<(), FlowyError> {
|
||||
let _ = self.send_msg(msg).map_err(internal_error)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
15
frontend/rust-lib/flowy-net/src/services/ws/mod.rs
Normal file
15
frontend/rust-lib/flowy-net/src/services/ws/mod.rs
Normal file
@ -0,0 +1,15 @@
|
||||
pub use conn::*;
|
||||
pub use manager::*;
|
||||
use std::sync::Arc;
|
||||
|
||||
mod conn;
|
||||
mod manager;
|
||||
mod ws_local;
|
||||
|
||||
#[cfg(not(feature = "ws_mock"))]
|
||||
pub(crate) fn local_web_socket() -> Arc<dyn FlowyWebSocket> { Arc::new(Arc::new(ws_local::LocalWebSocket::default())) }
|
||||
|
||||
#[cfg(feature = "ws_mock")]
|
||||
pub(crate) fn local_web_socket() -> Arc<dyn FlowyWebSocket> {
|
||||
Arc::new(Arc::new(crate::services::mock::MockWebSocket::default()))
|
||||
}
|
@ -1,9 +1,5 @@
|
||||
use crate::{
|
||||
errors::UserError,
|
||||
services::user::ws_manager::{FlowyWebSocket, FlowyWsSender},
|
||||
};
|
||||
use crate::services::ws::{FlowyError, FlowyWebSocket, FlowyWsSender, WsConnectState, WsMessage, WsMessageHandler};
|
||||
use lib_infra::future::FutureResult;
|
||||
use lib_ws::{WsConnectState, WsMessage, WsMessageHandler};
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{broadcast, broadcast::Receiver};
|
||||
|
||||
@ -24,19 +20,19 @@ impl std::default::Default for LocalWebSocket {
|
||||
}
|
||||
|
||||
impl FlowyWebSocket for Arc<LocalWebSocket> {
|
||||
fn start_connect(&self, _addr: String) -> FutureResult<(), UserError> { FutureResult::new(async { Ok(()) }) }
|
||||
fn start_connect(&self, _addr: String) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) }
|
||||
|
||||
fn conn_state_subscribe(&self) -> Receiver<WsConnectState> { self.state_sender.subscribe() }
|
||||
|
||||
fn reconnect(&self, _count: usize) -> FutureResult<(), UserError> { FutureResult::new(async { Ok(()) }) }
|
||||
fn reconnect(&self, _count: usize) -> FutureResult<(), FlowyError> { FutureResult::new(async { Ok(()) }) }
|
||||
|
||||
fn add_handler(&self, _handler: Arc<dyn WsMessageHandler>) -> Result<(), UserError> { Ok(()) }
|
||||
fn add_handler(&self, _handler: Arc<dyn WsMessageHandler>) -> Result<(), FlowyError> { Ok(()) }
|
||||
|
||||
fn ws_sender(&self) -> Result<Arc<dyn FlowyWsSender>, UserError> { Ok(Arc::new(self.ws_sender.clone())) }
|
||||
fn ws_sender(&self) -> Result<Arc<dyn FlowyWsSender>, FlowyError> { Ok(Arc::new(self.ws_sender.clone())) }
|
||||
}
|
||||
|
||||
impl FlowyWsSender for broadcast::Sender<WsMessage> {
|
||||
fn send(&self, msg: WsMessage) -> Result<(), UserError> {
|
||||
fn send(&self, msg: WsMessage) -> Result<(), FlowyError> {
|
||||
let _ = self.send(msg);
|
||||
Ok(())
|
||||
}
|
@ -6,6 +6,7 @@ use flowy_document::{
|
||||
module::DocumentUser,
|
||||
services::ws::{DocumentWebSocket, WsDocumentManager, WsStateReceiver},
|
||||
};
|
||||
use flowy_net::services::ws::WsManager;
|
||||
use flowy_user::{
|
||||
errors::{ErrorCode, UserError},
|
||||
services::user::UserSession,
|
||||
@ -13,27 +14,23 @@ use flowy_user::{
|
||||
use lib_ws::{WsMessage, WsMessageHandler, WsModule};
|
||||
use std::{convert::TryInto, path::Path, sync::Arc};
|
||||
|
||||
pub struct DocumentDepsResolver {
|
||||
user_session: Arc<UserSession>,
|
||||
}
|
||||
|
||||
pub struct DocumentDepsResolver();
|
||||
impl DocumentDepsResolver {
|
||||
pub fn new(user_session: Arc<UserSession>) -> Self { Self { user_session } }
|
||||
|
||||
pub fn split_into(self) -> (Arc<dyn DocumentUser>, Arc<WsDocumentManager>) {
|
||||
pub fn resolve(
|
||||
ws_manager: Arc<WsManager>,
|
||||
user_session: Arc<UserSession>,
|
||||
) -> (Arc<dyn DocumentUser>, Arc<WsDocumentManager>) {
|
||||
let user = Arc::new(DocumentUserImpl {
|
||||
user: self.user_session.clone(),
|
||||
user: user_session.clone(),
|
||||
});
|
||||
|
||||
let sender = Arc::new(WsSenderImpl {
|
||||
user: self.user_session.clone(),
|
||||
ws_manager: ws_manager.clone(),
|
||||
});
|
||||
let ws_manager = Arc::new(WsDocumentManager::new(sender));
|
||||
let ws_handler = Arc::new(DocumentWsMessageReceiver {
|
||||
inner: ws_manager.clone(),
|
||||
});
|
||||
self.user_session.add_ws_handler(ws_handler);
|
||||
(user, ws_manager)
|
||||
let ws_doc = Arc::new(WsDocumentManager::new(sender));
|
||||
let ws_handler = Arc::new(DocumentWsMessageReceiver { inner: ws_doc.clone() });
|
||||
ws_manager.add_handler(ws_handler);
|
||||
(user, ws_doc)
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +66,7 @@ impl DocumentUser for DocumentUserImpl {
|
||||
}
|
||||
|
||||
struct WsSenderImpl {
|
||||
user: Arc<UserSession>,
|
||||
ws_manager: Arc<WsManager>,
|
||||
}
|
||||
|
||||
impl DocumentWebSocket for WsSenderImpl {
|
||||
@ -79,13 +76,13 @@ impl DocumentWebSocket for WsSenderImpl {
|
||||
module: WsModule::Doc,
|
||||
data: bytes.to_vec(),
|
||||
};
|
||||
let sender = self.user.ws_sender().map_err(internal_error)?;
|
||||
let sender = self.ws_manager.ws_sender().map_err(internal_error)?;
|
||||
sender.send(msg).map_err(internal_error)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn state_notify(&self) -> WsStateReceiver { self.user.ws_state_notifier() }
|
||||
fn subscribe_state_changed(&self) -> WsStateReceiver { self.ws_manager.subscribe_websocket_state() }
|
||||
}
|
||||
|
||||
struct DocumentWsMessageReceiver {
|
||||
|
@ -1,11 +1,11 @@
|
||||
mod deps_resolve;
|
||||
// mod flowy_server;
|
||||
pub mod module;
|
||||
use crate::deps_resolve::WorkspaceDepsResolver;
|
||||
use crate::deps_resolve::{DocumentDepsResolver, WorkspaceDepsResolver};
|
||||
use backend_service::configuration::ClientServerConfiguration;
|
||||
use flowy_core::{errors::WorkspaceError, module::init_core, prelude::CoreContext};
|
||||
use flowy_document::module::FlowyDocument;
|
||||
use flowy_net::entities::NetworkType;
|
||||
use flowy_net::{entities::NetworkType, services::ws::WsManager};
|
||||
use flowy_user::{
|
||||
prelude::UserStatus,
|
||||
services::user::{UserSession, UserSessionConfig},
|
||||
@ -53,6 +53,7 @@ fn crate_log_filter(level: Option<String>) -> String {
|
||||
filters.push(format!("flowy_user={}", level));
|
||||
filters.push(format!("flowy_document={}", level));
|
||||
filters.push(format!("flowy_document_infra={}", level));
|
||||
filters.push(format!("flowy_net={}", level));
|
||||
filters.push(format!("dart_notify={}", level));
|
||||
filters.push(format!("lib_ot={}", level));
|
||||
filters.push(format!("lib_ws={}", level));
|
||||
@ -68,6 +69,7 @@ pub struct FlowySDK {
|
||||
pub flowy_document: Arc<FlowyDocument>,
|
||||
pub core: Arc<CoreContext>,
|
||||
pub dispatcher: Arc<EventDispatcher>,
|
||||
pub ws_manager: Arc<WsManager>,
|
||||
}
|
||||
|
||||
impl FlowySDK {
|
||||
@ -76,49 +78,59 @@ impl FlowySDK {
|
||||
init_kv(&config.root);
|
||||
tracing::debug!("🔥 {:?}", config);
|
||||
|
||||
let session_cache_key = format!("{}_session_cache", &config.name);
|
||||
let ws_manager = Arc::new(WsManager::new(config.server_config.ws_addr()));
|
||||
let user_session = mk_user_session(&config);
|
||||
let flowy_document = mk_document(ws_manager.clone(), user_session.clone(), &config.server_config);
|
||||
let core_ctx = mk_core_context(user_session.clone(), flowy_document.clone(), &config.server_config);
|
||||
|
||||
let user_config = UserSessionConfig::new(&config.root, &config.server_config, &session_cache_key);
|
||||
let user_session = Arc::new(UserSession::new(user_config));
|
||||
let flowy_document = mk_document_module(user_session.clone(), &config.server_config);
|
||||
let core = mk_core(user_session.clone(), flowy_document.clone(), &config.server_config);
|
||||
|
||||
let modules = mk_modules(core.clone(), user_session.clone());
|
||||
//
|
||||
let modules = mk_modules(ws_manager.clone(), core_ctx.clone(), user_session.clone());
|
||||
let dispatcher = Arc::new(EventDispatcher::construct(|| modules));
|
||||
_init(&dispatcher, user_session.clone(), core.clone());
|
||||
_init(&dispatcher, ws_manager.clone(), user_session.clone(), core_ctx.clone());
|
||||
|
||||
Self {
|
||||
config,
|
||||
user_session,
|
||||
flowy_document,
|
||||
core,
|
||||
core: core_ctx,
|
||||
dispatcher,
|
||||
ws_manager,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dispatcher(&self) -> Arc<EventDispatcher> { self.dispatcher.clone() }
|
||||
}
|
||||
|
||||
fn _init(dispatch: &EventDispatcher, user_session: Arc<UserSession>, core: Arc<CoreContext>) {
|
||||
let user_status_subscribe = user_session.notifier.user_status_subscribe();
|
||||
let network_status_subscribe = user_session.notifier.network_type_subscribe();
|
||||
fn _init(
|
||||
dispatch: &EventDispatcher,
|
||||
ws_manager: Arc<WsManager>,
|
||||
user_session: Arc<UserSession>,
|
||||
core: Arc<CoreContext>,
|
||||
) {
|
||||
let subscribe_user_status = user_session.notifier.subscribe_user_status();
|
||||
let subscribe_network_type = ws_manager.subscribe_network_ty();
|
||||
let cloned_core = core.clone();
|
||||
|
||||
dispatch.spawn(async move {
|
||||
user_session.init();
|
||||
_listen_user_status(user_status_subscribe, core.clone()).await;
|
||||
_listen_user_status(ws_manager, subscribe_user_status, core.clone()).await;
|
||||
});
|
||||
dispatch.spawn(async move {
|
||||
_listen_network_status(network_status_subscribe, cloned_core).await;
|
||||
_listen_network_status(subscribe_network_type, cloned_core).await;
|
||||
});
|
||||
}
|
||||
|
||||
async fn _listen_user_status(mut subscribe: broadcast::Receiver<UserStatus>, core: Arc<CoreContext>) {
|
||||
async fn _listen_user_status(
|
||||
ws_manager: Arc<WsManager>,
|
||||
mut subscribe: broadcast::Receiver<UserStatus>,
|
||||
core: Arc<CoreContext>,
|
||||
) {
|
||||
while let Ok(status) = subscribe.recv().await {
|
||||
let result = || async {
|
||||
match status {
|
||||
UserStatus::Login { token } => {
|
||||
let _ = core.user_did_sign_in(&token).await?;
|
||||
let _ = ws_manager.start(token).await.unwrap();
|
||||
},
|
||||
UserStatus::Logout { .. } => {
|
||||
core.user_did_logout().await;
|
||||
@ -164,7 +176,13 @@ fn init_log(config: &FlowySDKConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
fn mk_core(
|
||||
fn mk_user_session(config: &FlowySDKConfig) -> Arc<UserSession> {
|
||||
let session_cache_key = format!("{}_session_cache", &config.name);
|
||||
let user_config = UserSessionConfig::new(&config.root, &config.server_config, &session_cache_key);
|
||||
Arc::new(UserSession::new(user_config))
|
||||
}
|
||||
|
||||
fn mk_core_context(
|
||||
user_session: Arc<UserSession>,
|
||||
flowy_document: Arc<FlowyDocument>,
|
||||
server_config: &ClientServerConfiguration,
|
||||
@ -173,3 +191,12 @@ fn mk_core(
|
||||
let (user, database) = workspace_deps.split_into();
|
||||
init_core(user, database, flowy_document, server_config)
|
||||
}
|
||||
|
||||
pub fn mk_document(
|
||||
ws_manager: Arc<WsManager>,
|
||||
user_session: Arc<UserSession>,
|
||||
server_config: &ClientServerConfiguration,
|
||||
) -> Arc<FlowyDocument> {
|
||||
let (user, ws_doc) = DocumentDepsResolver::resolve(ws_manager, user_session);
|
||||
Arc::new(FlowyDocument::new(user, ws_doc, server_config))
|
||||
}
|
||||
|
@ -2,24 +2,20 @@ use crate::deps_resolve::DocumentDepsResolver;
|
||||
use backend_service::configuration::ClientServerConfiguration;
|
||||
use flowy_core::prelude::CoreContext;
|
||||
use flowy_document::module::FlowyDocument;
|
||||
use flowy_net::services::ws::WsManager;
|
||||
use flowy_user::services::user::UserSession;
|
||||
use lib_dispatch::prelude::Module;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub fn mk_modules(core: Arc<CoreContext>, user_session: Arc<UserSession>) -> Vec<Module> {
|
||||
pub fn mk_modules(ws_manager: Arc<WsManager>, core: Arc<CoreContext>, user_session: Arc<UserSession>) -> Vec<Module> {
|
||||
let user_module = mk_user_module(user_session);
|
||||
let workspace_module = mk_core_module(core);
|
||||
vec![user_module, workspace_module]
|
||||
let core_module = mk_core_module(core);
|
||||
let network_module = mk_network_module(ws_manager);
|
||||
vec![user_module, core_module, network_module]
|
||||
}
|
||||
|
||||
fn mk_user_module(user_session: Arc<UserSession>) -> Module { flowy_user::module::create(user_session) }
|
||||
|
||||
fn mk_core_module(core: Arc<CoreContext>) -> Module { flowy_core::module::create(core) }
|
||||
|
||||
pub fn mk_document_module(
|
||||
user_session: Arc<UserSession>,
|
||||
server_config: &ClientServerConfiguration,
|
||||
) -> Arc<FlowyDocument> {
|
||||
let document_deps = DocumentDepsResolver::new(user_session);
|
||||
let (user, ws_manager) = document_deps.split_into();
|
||||
Arc::new(FlowyDocument::new(user, ws_manager, server_config))
|
||||
}
|
||||
fn mk_network_module(ws_manager: Arc<WsManager>) -> Module { flowy_net::module::create(ws_manager) }
|
||||
|
@ -9,13 +9,10 @@ edition = "2018"
|
||||
flowy-user-infra = { path = "../../../shared-lib/flowy-user-infra" }
|
||||
backend-service = { path = "../../../shared-lib/backend-service" }
|
||||
flowy-derive = { path = "../../../shared-lib/flowy-derive" }
|
||||
lib-ws = { path = "../../../shared-lib/lib-ws" }
|
||||
lib-sqlite = { path = "../../../shared-lib/lib-sqlite" }
|
||||
lib-infra = { path = "../../../shared-lib/lib-infra" }
|
||||
|
||||
|
||||
flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration", optional = true}
|
||||
lib-ot = { path = "../../../shared-lib/lib-ot", optional = true }
|
||||
|
||||
derive_more = {version = "0.99", features = ["display"]}
|
||||
flowy-database = { path = "../flowy-database" }
|
||||
@ -51,5 +48,4 @@ futures = "0.3.15"
|
||||
serial_test = "0.5.1"
|
||||
|
||||
[features]
|
||||
http_server = []
|
||||
ws_mock = ["flowy-collaboration", "lib-ot"]
|
||||
http_server = []
|
@ -1,5 +1,4 @@
|
||||
use bytes::Bytes;
|
||||
|
||||
use flowy_derive::ProtoBuf;
|
||||
pub use flowy_user_infra::errors::ErrorCode;
|
||||
use lib_dispatch::prelude::{EventResponse, ResponseBuilder};
|
||||
@ -77,15 +76,6 @@ impl std::convert::From<::r2d2::Error> for UserError {
|
||||
fn from(error: r2d2::Error) -> Self { UserError::internal().context(error) }
|
||||
}
|
||||
|
||||
impl std::convert::From<lib_ws::errors::WsError> for UserError {
|
||||
fn from(error: lib_ws::errors::WsError) -> Self {
|
||||
match error.code {
|
||||
lib_ws::errors::ErrorCode::InternalError => UserError::internal().context(error.msg),
|
||||
_ => UserError::internal().context(error),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// use diesel::result::{Error, DatabaseErrorKind};
|
||||
// use lib_sqlite::ErrorKind;
|
||||
impl std::convert::From<lib_sqlite::Error> for UserError {
|
||||
|
@ -5,26 +5,23 @@ use strum_macros::Display;
|
||||
#[event_err = "UserError"]
|
||||
pub enum UserEvent {
|
||||
#[event()]
|
||||
InitUser = 0,
|
||||
InitUser = 0,
|
||||
|
||||
#[event(input = "SignInRequest", output = "UserProfile")]
|
||||
SignIn = 1,
|
||||
SignIn = 1,
|
||||
|
||||
#[event(input = "SignUpRequest", output = "UserProfile")]
|
||||
SignUp = 2,
|
||||
SignUp = 2,
|
||||
|
||||
#[event(passthrough)]
|
||||
SignOut = 3,
|
||||
SignOut = 3,
|
||||
|
||||
#[event(input = "UpdateUserRequest")]
|
||||
UpdateUser = 4,
|
||||
UpdateUser = 4,
|
||||
|
||||
#[event(output = "UserProfile")]
|
||||
GetUserProfile = 5,
|
||||
GetUserProfile = 5,
|
||||
|
||||
#[event(output = "UserProfile")]
|
||||
CheckUser = 6,
|
||||
|
||||
#[event(input = "NetworkState")]
|
||||
UpdateNetworkType = 10,
|
||||
CheckUser = 6,
|
||||
}
|
||||
|
@ -36,10 +36,3 @@ pub async fn update_user_handler(
|
||||
session.update_user(params).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(data, session))]
|
||||
pub async fn update_network_ty(data: Data<NetworkState>, session: Unit<Arc<UserSession>>) -> Result<(), UserError> {
|
||||
let network_state = data.into_inner();
|
||||
session.set_network_state(network_state);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -14,5 +14,4 @@ pub fn create(user_session: Arc<UserSession>) -> Module {
|
||||
.event(UserEvent::SignOut, sign_out)
|
||||
.event(UserEvent::UpdateUser, update_user_handler)
|
||||
.event(UserEvent::CheckUser, check_user_handler)
|
||||
.event(UserEvent::UpdateNetworkType, update_network_ty)
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ pub enum UserEvent {
|
||||
UpdateUser = 4,
|
||||
GetUserProfile = 5,
|
||||
CheckUser = 6,
|
||||
UpdateNetworkType = 10,
|
||||
}
|
||||
|
||||
impl ::protobuf::ProtobufEnum for UserEvent {
|
||||
@ -49,7 +48,6 @@ impl ::protobuf::ProtobufEnum for UserEvent {
|
||||
4 => ::std::option::Option::Some(UserEvent::UpdateUser),
|
||||
5 => ::std::option::Option::Some(UserEvent::GetUserProfile),
|
||||
6 => ::std::option::Option::Some(UserEvent::CheckUser),
|
||||
10 => ::std::option::Option::Some(UserEvent::UpdateNetworkType),
|
||||
_ => ::std::option::Option::None
|
||||
}
|
||||
}
|
||||
@ -63,7 +61,6 @@ impl ::protobuf::ProtobufEnum for UserEvent {
|
||||
UserEvent::UpdateUser,
|
||||
UserEvent::GetUserProfile,
|
||||
UserEvent::CheckUser,
|
||||
UserEvent::UpdateNetworkType,
|
||||
];
|
||||
values
|
||||
}
|
||||
@ -92,29 +89,26 @@ impl ::protobuf::reflect::ProtobufValue for UserEvent {
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\x0bevent.proto*\x88\x01\n\tUserEvent\x12\x0c\n\x08InitUser\x10\0\x12\
|
||||
\n\n\x06SignIn\x10\x01\x12\n\n\x06SignUp\x10\x02\x12\x0b\n\x07SignOut\
|
||||
\x10\x03\x12\x0e\n\nUpdateUser\x10\x04\x12\x12\n\x0eGetUserProfile\x10\
|
||||
\x05\x12\r\n\tCheckUser\x10\x06\x12\x15\n\x11UpdateNetworkType\x10\nJ\
|
||||
\xf2\x02\n\x06\x12\x04\0\0\x0b\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\
|
||||
\x02\x05\0\x12\x04\x02\0\x0b\x01\n\n\n\x03\x05\0\x01\x12\x03\x02\x05\x0e\
|
||||
\n\x0b\n\x04\x05\0\x02\0\x12\x03\x03\x04\x11\n\x0c\n\x05\x05\0\x02\0\x01\
|
||||
\x12\x03\x03\x04\x0c\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x03\x0f\x10\n\
|
||||
\x0b\n\x04\x05\0\x02\x01\x12\x03\x04\x04\x0f\n\x0c\n\x05\x05\0\x02\x01\
|
||||
\x01\x12\x03\x04\x04\n\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\x04\r\x0e\n\
|
||||
\x0b\n\x04\x05\0\x02\x02\x12\x03\x05\x04\x0f\n\x0c\n\x05\x05\0\x02\x02\
|
||||
\x01\x12\x03\x05\x04\n\n\x0c\n\x05\x05\0\x02\x02\x02\x12\x03\x05\r\x0e\n\
|
||||
\x0b\n\x04\x05\0\x02\x03\x12\x03\x06\x04\x10\n\x0c\n\x05\x05\0\x02\x03\
|
||||
\x01\x12\x03\x06\x04\x0b\n\x0c\n\x05\x05\0\x02\x03\x02\x12\x03\x06\x0e\
|
||||
\x0f\n\x0b\n\x04\x05\0\x02\x04\x12\x03\x07\x04\x13\n\x0c\n\x05\x05\0\x02\
|
||||
\x04\x01\x12\x03\x07\x04\x0e\n\x0c\n\x05\x05\0\x02\x04\x02\x12\x03\x07\
|
||||
\x11\x12\n\x0b\n\x04\x05\0\x02\x05\x12\x03\x08\x04\x17\n\x0c\n\x05\x05\0\
|
||||
\x02\x05\x01\x12\x03\x08\x04\x12\n\x0c\n\x05\x05\0\x02\x05\x02\x12\x03\
|
||||
\x08\x15\x16\n\x0b\n\x04\x05\0\x02\x06\x12\x03\t\x04\x12\n\x0c\n\x05\x05\
|
||||
\0\x02\x06\x01\x12\x03\t\x04\r\n\x0c\n\x05\x05\0\x02\x06\x02\x12\x03\t\
|
||||
\x10\x11\n\x0b\n\x04\x05\0\x02\x07\x12\x03\n\x04\x1b\n\x0c\n\x05\x05\0\
|
||||
\x02\x07\x01\x12\x03\n\x04\x15\n\x0c\n\x05\x05\0\x02\x07\x02\x12\x03\n\
|
||||
\x18\x1ab\x06proto3\
|
||||
\n\x0bevent.proto*q\n\tUserEvent\x12\x0c\n\x08InitUser\x10\0\x12\n\n\x06\
|
||||
SignIn\x10\x01\x12\n\n\x06SignUp\x10\x02\x12\x0b\n\x07SignOut\x10\x03\
|
||||
\x12\x0e\n\nUpdateUser\x10\x04\x12\x12\n\x0eGetUserProfile\x10\x05\x12\r\
|
||||
\n\tCheckUser\x10\x06J\xc9\x02\n\x06\x12\x04\0\0\n\x01\n\x08\n\x01\x0c\
|
||||
\x12\x03\0\0\x12\n\n\n\x02\x05\0\x12\x04\x02\0\n\x01\n\n\n\x03\x05\0\x01\
|
||||
\x12\x03\x02\x05\x0e\n\x0b\n\x04\x05\0\x02\0\x12\x03\x03\x04\x11\n\x0c\n\
|
||||
\x05\x05\0\x02\0\x01\x12\x03\x03\x04\x0c\n\x0c\n\x05\x05\0\x02\0\x02\x12\
|
||||
\x03\x03\x0f\x10\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x04\x04\x0f\n\x0c\n\
|
||||
\x05\x05\0\x02\x01\x01\x12\x03\x04\x04\n\n\x0c\n\x05\x05\0\x02\x01\x02\
|
||||
\x12\x03\x04\r\x0e\n\x0b\n\x04\x05\0\x02\x02\x12\x03\x05\x04\x0f\n\x0c\n\
|
||||
\x05\x05\0\x02\x02\x01\x12\x03\x05\x04\n\n\x0c\n\x05\x05\0\x02\x02\x02\
|
||||
\x12\x03\x05\r\x0e\n\x0b\n\x04\x05\0\x02\x03\x12\x03\x06\x04\x10\n\x0c\n\
|
||||
\x05\x05\0\x02\x03\x01\x12\x03\x06\x04\x0b\n\x0c\n\x05\x05\0\x02\x03\x02\
|
||||
\x12\x03\x06\x0e\x0f\n\x0b\n\x04\x05\0\x02\x04\x12\x03\x07\x04\x13\n\x0c\
|
||||
\n\x05\x05\0\x02\x04\x01\x12\x03\x07\x04\x0e\n\x0c\n\x05\x05\0\x02\x04\
|
||||
\x02\x12\x03\x07\x11\x12\n\x0b\n\x04\x05\0\x02\x05\x12\x03\x08\x04\x17\n\
|
||||
\x0c\n\x05\x05\0\x02\x05\x01\x12\x03\x08\x04\x12\n\x0c\n\x05\x05\0\x02\
|
||||
\x05\x02\x12\x03\x08\x15\x16\n\x0b\n\x04\x05\0\x02\x06\x12\x03\t\x04\x12\
|
||||
\n\x0c\n\x05\x05\0\x02\x06\x01\x12\x03\t\x04\r\n\x0c\n\x05\x05\0\x02\x06\
|
||||
\x02\x12\x03\t\x10\x11b\x06proto3\
|
||||
";
|
||||
|
||||
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;
|
||||
|
@ -8,5 +8,4 @@ enum UserEvent {
|
||||
UpdateUser = 4;
|
||||
GetUserProfile = 5;
|
||||
CheckUser = 6;
|
||||
UpdateNetworkType = 10;
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
mod server_api;
|
||||
mod server_api_mock;
|
||||
mod ws_local;
|
||||
|
||||
pub use server_api::*;
|
||||
pub use server_api_mock::*;
|
||||
@ -10,7 +9,6 @@ pub(crate) type Server = Arc<dyn UserServerAPI + Send + Sync>;
|
||||
use crate::{
|
||||
entities::{SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserParams, UserProfile},
|
||||
errors::UserError,
|
||||
services::user::ws_manager::FlowyWebSocket,
|
||||
};
|
||||
use backend_service::configuration::ClientServerConfiguration;
|
||||
use lib_infra::future::FutureResult;
|
||||
@ -31,12 +29,3 @@ pub(crate) fn construct_user_server(config: &ClientServerConfiguration) -> Arc<d
|
||||
Arc::new(UserServerMock {})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ws_mock")]
|
||||
mod ws_mock;
|
||||
|
||||
#[cfg(not(feature = "ws_mock"))]
|
||||
pub(crate) fn local_web_socket() -> Arc<dyn FlowyWebSocket> { Arc::new(Arc::new(ws_local::LocalWebSocket::default())) }
|
||||
|
||||
#[cfg(feature = "ws_mock")]
|
||||
pub(crate) fn local_web_socket() -> Arc<dyn FlowyWebSocket> { Arc::new(Arc::new(ws_mock::MockWebSocket::default())) }
|
||||
|
@ -3,4 +3,3 @@ pub use user_session::*;
|
||||
pub mod database;
|
||||
mod notifier;
|
||||
mod user_session;
|
||||
pub mod ws_manager;
|
||||
|
@ -4,17 +4,12 @@ use tokio::sync::{broadcast, mpsc};
|
||||
|
||||
pub struct UserNotifier {
|
||||
user_status_notifier: broadcast::Sender<UserStatus>,
|
||||
network_status_notifier: broadcast::Sender<NetworkType>,
|
||||
}
|
||||
|
||||
impl std::default::Default for UserNotifier {
|
||||
fn default() -> Self {
|
||||
let (user_status_notifier, _) = broadcast::channel(10);
|
||||
let (network_status_notifier, _) = broadcast::channel(10);
|
||||
UserNotifier {
|
||||
user_status_notifier,
|
||||
network_status_notifier,
|
||||
}
|
||||
UserNotifier { user_status_notifier }
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,11 +35,5 @@ impl UserNotifier {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn update_network_type(&self, ty: &NetworkType) { let _ = self.network_status_notifier.send(ty.clone()); }
|
||||
|
||||
pub fn user_status_subscribe(&self) -> broadcast::Receiver<UserStatus> { self.user_status_notifier.subscribe() }
|
||||
|
||||
pub fn network_type_subscribe(&self) -> broadcast::Receiver<NetworkType> {
|
||||
self.network_status_notifier.subscribe()
|
||||
}
|
||||
pub fn subscribe_user_status(&self) -> broadcast::Receiver<UserStatus> { self.user_status_notifier.subscribe() }
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ use flowy_database::{
|
||||
};
|
||||
use flowy_user_infra::entities::{SignInResponse, SignUpResponse};
|
||||
use lib_sqlite::ConnectionPool;
|
||||
use lib_ws::{WsConnectState, WsMessageHandler};
|
||||
|
||||
use crate::{
|
||||
entities::{SignInParams, SignUpParams, UpdateUserParams, UserProfile},
|
||||
@ -23,11 +22,7 @@ use crate::{
|
||||
notify::*,
|
||||
services::{
|
||||
server::{construct_user_server, Server},
|
||||
user::{
|
||||
database::UserDB,
|
||||
notifier::UserNotifier,
|
||||
ws_manager::{FlowyWsSender, WsManager},
|
||||
},
|
||||
user::{database::UserDB, notifier::UserNotifier},
|
||||
},
|
||||
sql_tables::{UserTable, UserTableChangeset},
|
||||
};
|
||||
@ -55,7 +50,6 @@ pub struct UserSession {
|
||||
#[allow(dead_code)]
|
||||
server: Server,
|
||||
session: RwLock<Option<Session>>,
|
||||
ws_manager: Arc<WsManager>,
|
||||
pub notifier: UserNotifier,
|
||||
}
|
||||
|
||||
@ -63,14 +57,12 @@ impl UserSession {
|
||||
pub fn new(config: UserSessionConfig) -> Self {
|
||||
let db = UserDB::new(&config.root_dir);
|
||||
let server = construct_user_server(&config.server_config);
|
||||
let ws_manager = Arc::new(WsManager::new());
|
||||
let notifier = UserNotifier::new();
|
||||
Self {
|
||||
database: db,
|
||||
config,
|
||||
server,
|
||||
session: RwLock::new(None),
|
||||
ws_manager,
|
||||
notifier,
|
||||
}
|
||||
}
|
||||
@ -153,12 +145,7 @@ impl UserSession {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn init_user(&self) -> Result<(), UserError> {
|
||||
let (_, token) = self.get_session()?.into_part();
|
||||
let _ = self.start_ws_connection(&token).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
pub async fn init_user(&self) -> Result<(), UserError> { Ok(()) }
|
||||
|
||||
pub async fn check_user(&self) -> Result<UserProfile, UserError> {
|
||||
let (user_id, token) = self.get_session()?.into_part();
|
||||
@ -191,21 +178,6 @@ impl UserSession {
|
||||
pub fn user_name(&self) -> Result<String, UserError> { Ok(self.get_session()?.name) }
|
||||
|
||||
pub fn token(&self) -> Result<String, UserError> { Ok(self.get_session()?.token) }
|
||||
|
||||
pub fn add_ws_handler(&self, handler: Arc<dyn WsMessageHandler>) { let _ = self.ws_manager.add_handler(handler); }
|
||||
|
||||
pub fn set_network_state(&self, new_state: NetworkState) {
|
||||
log::debug!("Network new state: {:?}", new_state);
|
||||
self.ws_manager.update_network_type(&new_state.ty);
|
||||
self.notifier.update_network_type(&new_state.ty);
|
||||
}
|
||||
|
||||
pub fn ws_sender(&self) -> Result<Arc<dyn FlowyWsSender>, UserError> {
|
||||
let sender = self.ws_manager.ws_sender()?;
|
||||
Ok(sender)
|
||||
}
|
||||
|
||||
pub fn ws_state_notifier(&self) -> broadcast::Receiver<WsConnectState> { self.ws_manager.state_subscribe() }
|
||||
}
|
||||
|
||||
impl UserSession {
|
||||
@ -302,13 +274,6 @@ impl UserSession {
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self, token))]
|
||||
pub async fn start_ws_connection(&self, token: &str) -> Result<(), UserError> {
|
||||
let addr = format!("{}/{}", self.server.ws_addr(), token);
|
||||
let _ = self.ws_manager.start(addr).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update_user(
|
||||
|
Reference in New Issue
Block a user