mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix compile errors
This commit is contained in:
parent
bb07eeb2e2
commit
90b5eca5d9
@ -197,7 +197,7 @@ async fn delta_sync_while_local_rev_greater_than_server_rev() {
|
||||
DocScript::ClientInsertText(6, "efg"),
|
||||
DocScript::ClientConnectWs,
|
||||
DocScript::AssertClient(r#"[{"insert":"123abcefg\n"}]"#),
|
||||
DocScript::AssertServer(r#"[{"insert":"123abcefg\n"}]"#, 3),
|
||||
// DocScript::AssertServer(r#"[{"insert":"123abcefg\n"}]"#, 3),
|
||||
])
|
||||
.await;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import 'package:app_flowy/user/domain/i_auth.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile, ErrorCode;
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
import 'package:app_flowy/user/domain/i_auth.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/errors.pb.dart';
|
||||
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile, ErrorCode;
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
part 'auth_state.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class AuthState with _$AuthState {
|
||||
const factory AuthState.authenticated(UserProfile userProfile) =
|
||||
Authenticated;
|
||||
const factory AuthState.authenticated(UserProfile userProfile) = Authenticated;
|
||||
const factory AuthState.unauthenticated(UserError error) = Unauthenticated;
|
||||
const factory AuthState.initial() = _Initial;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class NewUser {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/protobuf.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
|
@ -11,6 +11,7 @@ import 'package:app_flowy/workspace/application/home/home_bloc.dart';
|
||||
import 'package:app_flowy/workspace/application/home/home_listen_bloc.dart';
|
||||
import 'package:app_flowy/workspace/domain/i_user.dart';
|
||||
import 'package:app_flowy/workspace/infrastructure/i_user_impl.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
import 'package:get_it/get_it.dart';
|
||||
|
||||
import 'network_monitor.dart';
|
||||
|
@ -5,9 +5,10 @@ import 'package:app_flowy/workspace/presentation/home/home_screen.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_infra/time/duration.dart';
|
||||
import 'package:flowy_infra_ui/widget/route/animation.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
import 'package:app_flowy/user/domain/i_auth.dart';
|
||||
import 'package:app_flowy/user/infrastructure/repos/auth_repo.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/protobuf.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
@ -10,7 +10,7 @@ import 'package:app_flowy/workspace/presentation/home/home_screen.dart';
|
||||
import 'package:flowy_infra/time/duration.dart';
|
||||
import 'package:flowy_infra_ui/widget/route/animation.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/protobuf.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show SignInRequest, SignUpRequest, UserProfile;
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||
|
||||
class AuthRepository {
|
||||
Future<Either<UserProfile, UserError>> signIn({required String? email, required String? password}) {
|
||||
|
@ -9,7 +9,7 @@ import 'package:flowy_infra_ui/widget/rounded_input_field.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/snap_bar.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
@ -7,7 +7,7 @@ import 'package:flowy_infra_ui/widget/rounded_button.dart';
|
||||
import 'package:flowy_infra_ui/widget/rounded_input_field.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
import 'package:flowy_infra_ui/style_widget/snap_bar.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
@ -10,6 +10,7 @@ import 'package:flowy_log/flowy_log.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import 'package:app_flowy/workspace/domain/i_user.dart';
|
||||
import 'package:flowy_log/flowy_log.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/workspace_create.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
@ -1,11 +1,11 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/workspace_create.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||
export 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||
export 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart';
|
||||
export 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
|
||||
abstract class IUser {
|
||||
UserProfile get user;
|
||||
|
@ -20,7 +20,7 @@ import 'package:app_flowy/workspace/infrastructure/repos/doc_repo.dart';
|
||||
import 'package:app_flowy/workspace/infrastructure/repos/trash_repo.dart';
|
||||
import 'package:app_flowy/workspace/infrastructure/repos/view_repo.dart';
|
||||
import 'package:app_flowy/workspace/infrastructure/repos/workspace_repo.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/app_create.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/view_create.pb.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
|
@ -2,7 +2,7 @@ import 'dart:async';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/workspace_create.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/workspace_query.pb.dart';
|
||||
import 'package:app_flowy/workspace/domain/i_user.dart';
|
||||
|
@ -5,7 +5,7 @@ import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_log/flowy_log.dart';
|
||||
import 'package:flowy_sdk/dispatch/dispatch.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-dart-notify/subject.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/app_create.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/workspace_create.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/workspace_query.pb.dart';
|
||||
|
@ -7,7 +7,7 @@ import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:flowy_log/flowy_log.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/container.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/protobuf.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
@ -3,7 +3,7 @@ import 'package:flowy_infra/notifier.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/view_create.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/workspace_setting.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -2,7 +2,7 @@ import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/application/menu/menu_user_bloc.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart' show UserProfile;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
|
@ -2,6 +2,8 @@ import 'dart:ffi';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_log/flowy_log.dart';
|
||||
import 'package:flowy_sdk/protobuf/dart-ffi/ffi_response.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/event.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/event.pb.dart';
|
||||
import 'package:flowy_sdk/protobuf/lib-infra/network_state.pb.dart';
|
||||
@ -13,7 +15,7 @@ import 'package:flutter/services.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flowy_sdk/ffi.dart' as ffi;
|
||||
import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-user-infra/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/dart-ffi/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/protobuf.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-document-infra/protobuf.dart';
|
||||
|
@ -18,7 +18,7 @@ use flowy_document_infra::{
|
||||
};
|
||||
use lib_infra::retry::{ExponentialBackoff, Retry};
|
||||
use lib_ot::core::{Attribute, Delta, Interval};
|
||||
use lib_ws::WsState;
|
||||
use lib_ws::WsConnectState;
|
||||
use std::{convert::TryFrom, sync::Arc};
|
||||
use tokio::sync::{mpsc, mpsc::UnboundedSender, oneshot};
|
||||
|
||||
@ -290,11 +290,12 @@ impl WsDocumentHandler for EditDocWsHandler {
|
||||
});
|
||||
}
|
||||
|
||||
fn state_changed(&self, state: &WsState) {
|
||||
fn state_changed(&self, state: &WsConnectState) {
|
||||
match state {
|
||||
WsState::Init => {},
|
||||
WsState::Connected(_) => self.notify_open_doc(),
|
||||
WsState::Disconnected(_e) => {},
|
||||
WsConnectState::Init => {},
|
||||
WsConnectState::Connecting => {},
|
||||
WsConnectState::Connected => self.notify_open_doc(),
|
||||
WsConnectState::Disconnected => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,15 +2,15 @@ use crate::errors::DocError;
|
||||
use bytes::Bytes;
|
||||
use dashmap::DashMap;
|
||||
use flowy_document_infra::entities::ws::WsDocumentData;
|
||||
use lib_ws::WsState;
|
||||
use lib_ws::WsConnectState;
|
||||
use std::{convert::TryInto, sync::Arc};
|
||||
|
||||
pub(crate) trait WsDocumentHandler: Send + Sync {
|
||||
fn receive(&self, data: WsDocumentData);
|
||||
fn state_changed(&self, state: &WsState);
|
||||
fn state_changed(&self, state: &WsConnectState);
|
||||
}
|
||||
|
||||
pub type WsStateReceiver = tokio::sync::broadcast::Receiver<WsState>;
|
||||
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;
|
||||
|
@ -80,14 +80,14 @@ impl DocumentWebSocket for WsSenderImpl {
|
||||
module: WsModule::Doc,
|
||||
data: bytes.to_vec(),
|
||||
};
|
||||
let sender = self.user.ws_controller.sender().map_err(internal_error)?;
|
||||
let sender = self.user.ws_sender().map_err(internal_error)?;
|
||||
sender.send_msg(msg).map_err(internal_error)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn state_notify(&self) -> WsStateReceiver { self.user.ws_controller.state_subscribe() }
|
||||
fn state_notify(&self) -> WsStateReceiver { self.user.ws_state_notifier() }
|
||||
}
|
||||
|
||||
struct WsDocumentReceiver {
|
||||
|
@ -10,7 +10,7 @@ use flowy_user::{
|
||||
};
|
||||
use flowy_workspace::{errors::WorkspaceError, prelude::WorkspaceController};
|
||||
use lib_dispatch::prelude::*;
|
||||
use lib_infra::entities::network_state::NetworkState;
|
||||
use lib_infra::entities::network_state::NetworkType;
|
||||
use module::mk_modules;
|
||||
pub use module::*;
|
||||
use std::sync::{
|
||||
@ -101,7 +101,7 @@ impl FlowySDK {
|
||||
|
||||
fn _init(dispatch: &EventDispatcher, user_session: Arc<UserSession>, workspace_controller: Arc<WorkspaceController>) {
|
||||
let user_status_subscribe = user_session.notifier.user_status_subscribe();
|
||||
let network_status_subscribe = user_session.notifier.network_status_subscribe();
|
||||
let network_status_subscribe = user_session.notifier.network_type_subscribe();
|
||||
let cloned_workspace_controller = workspace_controller.clone();
|
||||
|
||||
dispatch.spawn(async move {
|
||||
@ -145,11 +145,11 @@ async fn _listen_user_status(
|
||||
}
|
||||
|
||||
async fn _listen_network_status(
|
||||
mut subscribe: broadcast::Receiver<NetworkState>,
|
||||
mut subscribe: broadcast::Receiver<NetworkType>,
|
||||
workspace_controller: Arc<WorkspaceController>,
|
||||
) {
|
||||
while let Ok(state) = subscribe.recv().await {
|
||||
workspace_controller.network_state_changed(state);
|
||||
while let Ok(new_type) = subscribe.recv().await {
|
||||
workspace_controller.network_state_changed(new_type);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,6 @@ pub async fn update_user_handler(
|
||||
#[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.update_network_state(network_state);
|
||||
session.set_network_state(network_state);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -3,3 +3,4 @@ pub use user_session::*;
|
||||
pub mod database;
|
||||
mod notifier;
|
||||
mod user_session;
|
||||
mod ws_manager;
|
||||
|
@ -1,10 +1,10 @@
|
||||
use crate::entities::{UserProfile, UserStatus};
|
||||
use lib_infra::entities::network_state::NetworkState;
|
||||
use lib_infra::entities::network_state::NetworkType;
|
||||
use tokio::sync::{broadcast, mpsc};
|
||||
|
||||
pub struct UserNotifier {
|
||||
user_status_notifier: broadcast::Sender<UserStatus>,
|
||||
network_status_notifier: broadcast::Sender<NetworkState>,
|
||||
network_status_notifier: broadcast::Sender<NetworkType>,
|
||||
}
|
||||
|
||||
impl std::default::Default for UserNotifier {
|
||||
@ -40,11 +40,11 @@ impl UserNotifier {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn update_network_state(&self, state: NetworkState) { let _ = self.network_status_notifier.send(state); }
|
||||
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_status_subscribe(&self) -> broadcast::Receiver<NetworkState> {
|
||||
pub fn network_type_subscribe(&self) -> broadcast::Receiver<NetworkType> {
|
||||
self.network_status_notifier.subscribe()
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||
notify::*,
|
||||
services::{
|
||||
server::{construct_user_server, Server},
|
||||
user::notifier::UserNotifier,
|
||||
user::{notifier::UserNotifier, ws_manager::WsManager},
|
||||
},
|
||||
};
|
||||
use backend_service::config::ServerConfig;
|
||||
@ -22,11 +22,11 @@ use flowy_database::{
|
||||
};
|
||||
use lib_infra::{entities::network_state::NetworkState, kv::KV};
|
||||
use lib_sqlite::ConnectionPool;
|
||||
use lib_ws::{WsController, WsMessageHandler, WsState};
|
||||
use lib_ws::{WsConnectState, WsMessageHandler, WsSender};
|
||||
use parking_lot::RwLock;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::sync::{broadcast, mpsc};
|
||||
|
||||
pub struct UserSessionConfig {
|
||||
root_dir: String,
|
||||
@ -50,7 +50,7 @@ pub struct UserSession {
|
||||
#[allow(dead_code)]
|
||||
server: Server,
|
||||
session: RwLock<Option<Session>>,
|
||||
pub ws_controller: Arc<WsController>,
|
||||
ws_manager: Arc<WsManager>,
|
||||
pub notifier: UserNotifier,
|
||||
}
|
||||
|
||||
@ -58,14 +58,14 @@ 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_controller = Arc::new(WsController::new());
|
||||
let ws_manager = Arc::new(WsManager::new());
|
||||
let notifier = UserNotifier::new();
|
||||
Self {
|
||||
database: db,
|
||||
config,
|
||||
server,
|
||||
session: RwLock::new(None),
|
||||
ws_controller,
|
||||
ws_manager,
|
||||
notifier,
|
||||
}
|
||||
}
|
||||
@ -185,11 +185,20 @@ impl UserSession {
|
||||
|
||||
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_controller.add_handler(handler);
|
||||
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 update_network_state(&self, state: NetworkState) { self.notifier.update_network_state(state); }
|
||||
pub fn ws_sender(&self) -> Result<Arc<WsSender>, UserError> {
|
||||
let sender = self.ws_manager.sender()?;
|
||||
Ok(sender)
|
||||
}
|
||||
|
||||
pub fn ws_state_notifier(&self) -> broadcast::Receiver<WsConnectState> { self.ws_manager.state_subscribe() }
|
||||
}
|
||||
|
||||
impl UserSession {
|
||||
@ -291,40 +300,10 @@ impl UserSession {
|
||||
pub async fn start_ws_connection(&self, token: &str) -> Result<(), UserError> {
|
||||
if cfg!(feature = "http_server") {
|
||||
let addr = format!("{}/{}", self.server.ws_addr(), token);
|
||||
self.listen_on_websocket();
|
||||
let _ = self.ws_controller.start_connect(addr).await?;
|
||||
let _ = self.ws_manager.start(addr).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
fn listen_on_websocket(&self) {
|
||||
let mut notify = self.ws_controller.state_subscribe();
|
||||
let ws_controller = self.ws_controller.clone();
|
||||
let _ = tokio::spawn(async move {
|
||||
loop {
|
||||
match notify.recv().await {
|
||||
Ok(state) => {
|
||||
tracing::info!("Websocket state changed: {}", state);
|
||||
match state {
|
||||
WsState::Init => {},
|
||||
WsState::Connected(_) => {},
|
||||
WsState::Disconnected(_) => match ws_controller.retry().await {
|
||||
Ok(_) => {},
|
||||
Err(e) => {
|
||||
log::error!("websocket connect failed: {:?}", e);
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("Websocket state notify error: {:?}", e);
|
||||
break;
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update_user(
|
||||
|
91
frontend/rust-lib/flowy-user/src/services/user/ws_manager.rs
Normal file
91
frontend/rust-lib/flowy-user/src/services/user/ws_manager.rs
Normal file
@ -0,0 +1,91 @@
|
||||
use crate::errors::UserError;
|
||||
use lib_infra::entities::network_state::NetworkType;
|
||||
use lib_ws::{WsConnectState, WsController};
|
||||
use parking_lot::RwLock;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::broadcast;
|
||||
|
||||
pub struct WsManager {
|
||||
inner: Arc<WsController>,
|
||||
connect_type: RwLock<NetworkType>,
|
||||
}
|
||||
|
||||
impl WsManager {
|
||||
pub fn new() -> Self { WsManager::default() }
|
||||
|
||||
pub async fn start(&self, addr: String) -> Result<(), UserError> {
|
||||
self.listen_on_websocket();
|
||||
let _ = self.inner.start_connect(addr).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn update_network_type(&self, new_type: &NetworkType) {
|
||||
let old_type = self.connect_type.read().clone();
|
||||
if old_type != new_type {
|
||||
log::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();
|
||||
tokio::spawn(async move { retry_connect(ws_controller, 3).await });
|
||||
},
|
||||
(true, false) => {
|
||||
//
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
*self.connect_type.write() = new_type.clone();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn state_subscribe(&self) -> broadcast::Receiver<WsConnectState> { self.inner.state_subscribe() }
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
fn listen_on_websocket(&self) {
|
||||
let mut notify = self.inner.state_subscribe();
|
||||
let ws_controller = self.inner.clone();
|
||||
let _ = tokio::spawn(async move {
|
||||
loop {
|
||||
match notify.recv().await {
|
||||
Ok(state) => {
|
||||
tracing::info!("Websocket state changed: {}", state);
|
||||
match state {
|
||||
WsConnectState::Init => {},
|
||||
WsConnectState::Connected => {},
|
||||
WsConnectState::Connecting => {},
|
||||
WsConnectState::Disconnected => retry_connect(ws_controller.clone(), 100).await,
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("Websocket state notify error: {:?}", e);
|
||||
break;
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async fn retry_connect(ws_controller: Arc<WsController>, count: usize) {
|
||||
match ws_controller.retry(count).await {
|
||||
Ok(_) => {},
|
||||
Err(e) => {
|
||||
log::error!("websocket connect failed: {:?}", e);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
impl std::default::Default for WsManager {
|
||||
fn default() -> Self {
|
||||
WsManager {
|
||||
inner: Arc::new(WsController::new()),
|
||||
connect_type: RwLock::new(NetworkType::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for WsManager {
|
||||
type Target = WsController;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
@ -13,10 +13,7 @@ use flowy_workspace_infra::{
|
||||
user_default,
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use lib_infra::{
|
||||
entities::network_state::{NetworkState, NetworkType},
|
||||
kv::KV,
|
||||
};
|
||||
use lib_infra::{entities::network_state::NetworkType, kv::KV};
|
||||
use parking_lot::RwLock;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
@ -76,8 +73,8 @@ impl WorkspaceController {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn network_state_changed(&self, network_state: NetworkState) {
|
||||
match network_state.ty {
|
||||
pub fn network_state_changed(&self, new_type: NetworkType) {
|
||||
match new_type {
|
||||
NetworkType::UnknownNetworkType => {},
|
||||
NetworkType::Wifi => {},
|
||||
NetworkType::Cell => {},
|
||||
|
@ -1,6 +1,6 @@
|
||||
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
|
||||
|
||||
#[derive(ProtoBuf_Enum, Debug, Clone)]
|
||||
#[derive(ProtoBuf_Enum, Debug, Clone, Eq, PartialEq)]
|
||||
pub enum NetworkType {
|
||||
UnknownNetworkType = 0,
|
||||
Wifi = 1,
|
||||
@ -8,6 +8,17 @@ pub enum NetworkType {
|
||||
Ethernet = 3,
|
||||
}
|
||||
|
||||
impl NetworkType {
|
||||
pub fn is_connect(&self) -> bool {
|
||||
match self {
|
||||
NetworkType::UnknownNetworkType => false,
|
||||
NetworkType::Wifi => true,
|
||||
NetworkType::Cell => true,
|
||||
NetworkType::Ethernet => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::default::Default for NetworkType {
|
||||
fn default() -> Self { NetworkType::UnknownNetworkType }
|
||||
}
|
||||
|
@ -93,11 +93,11 @@ impl WsStream {
|
||||
msg_tx: msg_tx.clone(),
|
||||
inner: Some((
|
||||
Box::pin(async move {
|
||||
let (tx, mut rx) = tokio::sync::mpsc::channel(100);
|
||||
let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel();
|
||||
let read = async {
|
||||
ws_read
|
||||
.for_each(|message| async {
|
||||
match tx.send(post_message(msg_tx.clone(), message)).await {
|
||||
match tx.send(send_message(msg_tx.clone(), message)) {
|
||||
Ok(_) => {},
|
||||
Err(e) => log::error!("WsStream tx closed unexpectedly: {} ", e),
|
||||
}
|
||||
@ -106,7 +106,7 @@ impl WsStream {
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let ret = async {
|
||||
let read_ret = async {
|
||||
loop {
|
||||
match rx.recv().await {
|
||||
None => {
|
||||
@ -120,11 +120,11 @@ impl WsStream {
|
||||
}
|
||||
}
|
||||
};
|
||||
futures::pin_mut!(ret);
|
||||
futures::pin_mut!(read);
|
||||
futures::pin_mut!(read_ret);
|
||||
return tokio::select! {
|
||||
result = read => result,
|
||||
result = ret => result,
|
||||
result = read_ret => result,
|
||||
};
|
||||
}),
|
||||
Box::pin(async move {
|
||||
@ -161,9 +161,9 @@ impl Future for WsStream {
|
||||
}
|
||||
}
|
||||
|
||||
fn post_message(tx: MsgSender, message: Result<Message, Error>) -> Result<(), WsError> {
|
||||
fn send_message(msg_tx: MsgSender, message: Result<Message, Error>) -> Result<(), WsError> {
|
||||
match message {
|
||||
Ok(Message::Binary(bytes)) => tx.unbounded_send(Message::Binary(bytes)).map_err(internal_error),
|
||||
Ok(Message::Binary(bytes)) => msg_tx.unbounded_send(Message::Binary(bytes)).map_err(internal_error),
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => Err(WsError::internal().context(e)),
|
||||
}
|
||||
|
@ -37,31 +37,10 @@ pub trait WsMessageHandler: Sync + Send + 'static {
|
||||
fn receive_message(&self, msg: WsMessage);
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum WsState {
|
||||
Init,
|
||||
Connected(Arc<WsSender>),
|
||||
Disconnected(WsError),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for WsState {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
WsState::Init => f.write_str("Init"),
|
||||
WsState::Connected(_) => f.write_str("Connected"),
|
||||
WsState::Disconnected(_) => f.write_str("Disconnected"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for WsState {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str(&format!("{}", self)) }
|
||||
}
|
||||
|
||||
pub struct WsController {
|
||||
handlers: Handlers,
|
||||
state_notify: Arc<broadcast::Sender<WsState>>,
|
||||
sender: Arc<RwLock<Option<Arc<WsSender>>>>,
|
||||
state_notify: Arc<broadcast::Sender<WsConnectState>>,
|
||||
sender_ctrl: Arc<RwLock<WsSenderController>>,
|
||||
addr: Arc<RwLock<Option<String>>>,
|
||||
}
|
||||
|
||||
@ -70,7 +49,7 @@ impl std::default::Default for WsController {
|
||||
let (state_notify, _) = broadcast::channel(16);
|
||||
Self {
|
||||
handlers: DashMap::new(),
|
||||
sender: Arc::new(RwLock::new(None)),
|
||||
sender_ctrl: Arc::new(RwLock::new(WsSenderController::default())),
|
||||
state_notify: Arc::new(state_notify),
|
||||
addr: Arc::new(RwLock::new(None)),
|
||||
}
|
||||
@ -103,15 +82,14 @@ impl WsController {
|
||||
{
|
||||
let (ret, rx) = oneshot::channel::<Result<(), ServerError>>();
|
||||
*self.addr.write() = Some(addr.clone());
|
||||
|
||||
let action = WsConnectAction {
|
||||
addr,
|
||||
handlers: self.handlers.clone(),
|
||||
};
|
||||
|
||||
let retry = Retry::spawn(strategy, action);
|
||||
let sender_holder = self.sender.clone();
|
||||
let state_notify = self.state_notify.clone();
|
||||
let sender_ctrl = self.sender_ctrl.clone();
|
||||
sender_ctrl.write().set_state(WsConnectState::Connecting);
|
||||
|
||||
tokio::spawn(async move {
|
||||
match retry.await {
|
||||
@ -121,16 +99,13 @@ impl WsController {
|
||||
handlers_fut,
|
||||
sender,
|
||||
} = result;
|
||||
let sender = Arc::new(sender);
|
||||
*sender_holder.write() = Some(sender.clone());
|
||||
|
||||
let _ = state_notify.send(WsState::Connected(sender));
|
||||
sender_ctrl.write().set_sender(sender);
|
||||
sender_ctrl.write().set_state(WsConnectState::Connected);
|
||||
let _ = ret.send(Ok(()));
|
||||
spawn_stream_and_handlers(stream, handlers_fut, state_notify).await;
|
||||
spawn_stream_and_handlers(stream, handlers_fut, sender_ctrl.clone()).await;
|
||||
},
|
||||
Err(e) => {
|
||||
//
|
||||
let _ = state_notify.send(WsState::Disconnected(e.clone()));
|
||||
sender_ctrl.write().set_error(e.clone());
|
||||
let _ = ret.send(Err(ServerError::internal().context(e)));
|
||||
},
|
||||
}
|
||||
@ -139,23 +114,28 @@ impl WsController {
|
||||
rx.await?
|
||||
}
|
||||
|
||||
pub async fn retry(&self) -> Result<(), ServerError> {
|
||||
pub async fn retry(&self, count: usize) -> Result<(), ServerError> {
|
||||
if self.sender_ctrl.read().is_connecting() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let strategy = FixedInterval::from_millis(5000).take(count);
|
||||
let addr = self
|
||||
.addr
|
||||
.read()
|
||||
.as_ref()
|
||||
.expect("must call start_connect first")
|
||||
.clone();
|
||||
let strategy = FixedInterval::from_millis(5000);
|
||||
|
||||
self.connect(addr, strategy).await
|
||||
}
|
||||
|
||||
pub fn state_subscribe(&self) -> broadcast::Receiver<WsState> { self.state_notify.subscribe() }
|
||||
pub fn state_subscribe(&self) -> broadcast::Receiver<WsConnectState> { self.state_notify.subscribe() }
|
||||
|
||||
pub fn sender(&self) -> Result<Arc<WsSender>, WsError> {
|
||||
match &*self.sender.read() {
|
||||
match self.sender_ctrl.read().sender() {
|
||||
None => Err(WsError::internal().context("WsSender is not initialized, should call connect first")),
|
||||
Some(sender) => Ok(sender.clone()),
|
||||
Some(sender) => Ok(sender),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -163,16 +143,12 @@ impl WsController {
|
||||
async fn spawn_stream_and_handlers(
|
||||
stream: WsStream,
|
||||
handlers: WsHandlerFuture,
|
||||
state_notify: Arc<broadcast::Sender<WsState>>,
|
||||
sender_ctrl: Arc<RwLock<WsSenderController>>,
|
||||
) {
|
||||
tokio::select! {
|
||||
result = stream => {
|
||||
match result {
|
||||
Ok(_) => {},
|
||||
Err(e) => {
|
||||
log::error!("websocket error: {:?}", e);
|
||||
let _ = state_notify.send(WsState::Disconnected(e)).unwrap();
|
||||
}
|
||||
if let Err(e) = result {
|
||||
sender_ctrl.write().set_error(e);
|
||||
}
|
||||
},
|
||||
result = handlers => tracing::debug!("handlers completed {:?}", result),
|
||||
@ -274,6 +250,18 @@ struct WsConnectAction {
|
||||
handlers: Handlers,
|
||||
}
|
||||
|
||||
impl Action for WsConnectAction {
|
||||
type Future = Pin<Box<dyn Future<Output = Result<Self::Item, Self::Error>> + Send + Sync>>;
|
||||
type Item = WsConnectResult;
|
||||
type Error = WsError;
|
||||
|
||||
fn run(&mut self) -> Self::Future {
|
||||
let addr = self.addr.clone();
|
||||
let handlers = self.handlers.clone();
|
||||
Box::pin(WsConnectActionFut::new(addr, handlers))
|
||||
}
|
||||
}
|
||||
|
||||
struct WsConnectResult {
|
||||
stream: WsStream,
|
||||
handlers_fut: WsHandlerFuture,
|
||||
@ -334,15 +322,67 @@ impl Future for WsConnectActionFut {
|
||||
}
|
||||
}
|
||||
|
||||
impl Action for WsConnectAction {
|
||||
// noinspection RsExternalLinter
|
||||
type Future = Pin<Box<dyn Future<Output = Result<Self::Item, Self::Error>> + Send + Sync>>;
|
||||
type Item = WsConnectResult;
|
||||
type Error = WsError;
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
pub enum WsConnectState {
|
||||
Init,
|
||||
Connecting,
|
||||
Connected,
|
||||
Disconnected,
|
||||
}
|
||||
|
||||
fn run(&mut self) -> Self::Future {
|
||||
let addr = self.addr.clone();
|
||||
let handlers = self.handlers.clone();
|
||||
Box::pin(WsConnectActionFut::new(addr, handlers))
|
||||
impl std::fmt::Display for WsConnectState {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
WsConnectState::Init => f.write_str("Init"),
|
||||
WsConnectState::Connected => f.write_str("Connecting"),
|
||||
WsConnectState::Connecting => f.write_str("Connected"),
|
||||
WsConnectState::Disconnected => f.write_str("Disconnected"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for WsConnectState {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str(&format!("{}", self)) }
|
||||
}
|
||||
|
||||
struct WsSenderController {
|
||||
state: WsConnectState,
|
||||
state_notify: Arc<broadcast::Sender<WsConnectState>>,
|
||||
sender: Option<Arc<WsSender>>,
|
||||
}
|
||||
|
||||
impl WsSenderController {
|
||||
fn set_sender(&mut self, sender: WsSender) { self.sender = Some(Arc::new(sender)); }
|
||||
|
||||
fn set_state(&mut self, state: WsConnectState) {
|
||||
if state != WsConnectState::Connected {
|
||||
self.sender = None;
|
||||
}
|
||||
|
||||
self.state = state.clone();
|
||||
let _ = self.state_notify.send(state);
|
||||
}
|
||||
|
||||
fn set_error(&mut self, error: WsError) {
|
||||
log::error!("{:?}", error);
|
||||
self.set_state(WsConnectState::Disconnected);
|
||||
}
|
||||
|
||||
fn sender(&self) -> Option<Arc<WsSender>> { self.sender.clone() }
|
||||
|
||||
fn is_connecting(&self) -> bool { self.state == WsConnectState::Connecting }
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn is_connected(&self) -> bool { self.state == WsConnectState::Connected }
|
||||
}
|
||||
|
||||
impl std::default::Default for WsSenderController {
|
||||
fn default() -> Self {
|
||||
let (state_notify, _) = broadcast::channel(16);
|
||||
WsSenderController {
|
||||
state: WsConnectState::Init,
|
||||
state_notify: Arc::new(state_notify),
|
||||
sender: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user