mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
add tracing & test post data to dart
This commit is contained in:
parent
1cfcdab124
commit
77aa18d737
3
.gitignore
vendored
3
.gitignore
vendored
@ -8,6 +8,3 @@ Cargo.lock
|
|||||||
|
|
||||||
# These are backup files generated by rustfmt
|
# These are backup files generated by rustfmt
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
|
||||||
|
|
||||||
/rust-lib/flowy-derive
|
|
@ -524,14 +524,6 @@
|
|||||||
</list>
|
</list>
|
||||||
</value>
|
</value>
|
||||||
</entry>
|
</entry>
|
||||||
<entry key="protobuf">
|
|
||||||
<value>
|
|
||||||
<list>
|
|
||||||
<option value="$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/protobuf-2.0.0/lib" />
|
|
||||||
<option value="$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/protobuf-1.1.0/lib" />
|
|
||||||
</list>
|
|
||||||
</value>
|
|
||||||
</entry>
|
|
||||||
<entry key="provider">
|
<entry key="provider">
|
||||||
<value>
|
<value>
|
||||||
<list>
|
<list>
|
||||||
@ -841,8 +833,6 @@
|
|||||||
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/plugin_platform_interface-2.0.0/lib" />
|
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/plugin_platform_interface-2.0.0/lib" />
|
||||||
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/pool-1.5.0/lib" />
|
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/pool-1.5.0/lib" />
|
||||||
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/process-4.2.1/lib" />
|
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/process-4.2.1/lib" />
|
||||||
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/protobuf-1.1.0/lib" />
|
|
||||||
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/protobuf-2.0.0/lib" />
|
|
||||||
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/provider-5.0.0/lib" />
|
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/provider-5.0.0/lib" />
|
||||||
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/pub_semver-2.0.0/lib" />
|
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/pub_semver-2.0.0/lib" />
|
||||||
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/pubspec_parse-1.0.0/lib" />
|
<root url="file://$PROJECT_DIR$/../../flutter/.pub-cache/hosted/pub.dartlang.org/pubspec_parse-1.0.0/lib" />
|
||||||
|
1
app_flowy/.vscode/launch.json
vendored
1
app_flowy/.vscode/launch.json
vendored
@ -9,6 +9,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceRoot}/lib/main.dart",
|
"program": "${workspaceRoot}/lib/main.dart",
|
||||||
"type": "dart",
|
"type": "dart",
|
||||||
|
// "preLaunchTask": "build rust sdk"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "app_flowy (profile mode)",
|
"name": "app_flowy (profile mode)",
|
||||||
|
@ -25,7 +25,7 @@ class App {
|
|||||||
resolveDependencies(env);
|
resolveDependencies(env);
|
||||||
|
|
||||||
// add task
|
// add task
|
||||||
// getIt<AppLauncher>().addTask(RustSDKInitTask());
|
getIt<AppLauncher>().addTask(RustSDKInitTask());
|
||||||
getIt<AppLauncher>().addTask(AppWidgetTask());
|
getIt<AppLauncher>().addTask(AppWidgetTask());
|
||||||
|
|
||||||
// execute the tasks
|
// execute the tasks
|
||||||
|
@ -92,13 +92,6 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.1"
|
version: "6.1.1"
|
||||||
fixnum:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: fixnum
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.10.11"
|
|
||||||
flowy_logger:
|
flowy_logger:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -106,13 +99,6 @@ packages:
|
|||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "0.0.1"
|
version: "0.0.1"
|
||||||
flowy_protobuf:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
path: "../../flowy_protobuf"
|
|
||||||
relative: true
|
|
||||||
source: path
|
|
||||||
version: "0.0.1"
|
|
||||||
flowy_sdk:
|
flowy_sdk:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -215,13 +201,6 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.1"
|
version: "4.2.1"
|
||||||
protobuf:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: protobuf
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:convert';
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
// ignore: import_of_legacy_library_into_null_safe
|
// ignore: import_of_legacy_library_into_null_safe
|
||||||
import 'package:isolates/isolates.dart';
|
import 'package:isolates/isolates.dart';
|
||||||
@ -5,7 +6,7 @@ import 'package:isolates/isolates.dart';
|
|||||||
import 'package:isolates/ports.dart';
|
import 'package:isolates/ports.dart';
|
||||||
import 'package:ffi/ffi.dart';
|
import 'package:ffi/ffi.dart';
|
||||||
|
|
||||||
import 'package:flowy_protobuf/model/grpc.pb.dart';
|
// ignore: unused_import
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
@ -22,9 +23,25 @@ class FFIAdaptorException implements Exception {
|
|||||||
FFIAdaptorException(this.type);
|
FFIAdaptorException(this.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FFICommand {
|
||||||
|
final String event;
|
||||||
|
final Uint8List payload;
|
||||||
|
FFICommand(this.event, this.payload);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
'event': event,
|
||||||
|
'payload': payload,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
class FFIAdaptor {
|
class FFIAdaptor {
|
||||||
static Completer<Uint8List> asyncRequest(RequestPacket request) {
|
static Completer<Uint8List> asyncRequest() {
|
||||||
Uint8List bytes = request.writeToBuffer();
|
// final command = FFICommand(
|
||||||
|
// "AuthCheck", Uint8List.fromList(utf8.encode("this is payload")));
|
||||||
|
|
||||||
|
final command = FFICommand("AuthCheck", Uint8List(0));
|
||||||
|
|
||||||
|
Uint8List bytes = Uint8List.fromList(utf8.encode(jsonEncode(command)));
|
||||||
|
|
||||||
assert(bytes.isEmpty == false);
|
assert(bytes.isEmpty == false);
|
||||||
if (bytes.isEmpty) {
|
if (bytes.isEmpty) {
|
||||||
@ -43,4 +60,3 @@ class FFIAdaptor {
|
|||||||
return completer;
|
return completer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,25 +45,24 @@ typedef _invoke_async_Dart = void Function(
|
|||||||
int len,
|
int len,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/// C function `command_sync`.
|
/// C function `command_sync`.
|
||||||
Pointer<Uint8> sync_command(
|
Pointer<Uint8> sync_command(
|
||||||
Pointer<Uint8> input,
|
Pointer<Uint8> input,
|
||||||
int len,
|
int len,
|
||||||
) {
|
) {
|
||||||
return _invoke_sync(input, len);
|
return _invoke_sync(input, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
final _invoke_sync_Dart _invoke_sync =
|
final _invoke_sync_Dart _invoke_sync =
|
||||||
_dl.lookupFunction<_invoke_sync_C, _invoke_sync_Dart>('sync_command');
|
_dl.lookupFunction<_invoke_sync_C, _invoke_sync_Dart>('sync_command');
|
||||||
typedef _invoke_sync_C = Pointer<Uint8> Function(
|
typedef _invoke_sync_C = Pointer<Uint8> Function(
|
||||||
Pointer<Uint8> input,
|
Pointer<Uint8> input,
|
||||||
Uint64 len,
|
Uint64 len,
|
||||||
);
|
);
|
||||||
typedef _invoke_sync_Dart = Pointer<Uint8> Function(
|
typedef _invoke_sync_Dart = Pointer<Uint8> Function(
|
||||||
Pointer<Uint8> input,
|
Pointer<Uint8> input,
|
||||||
int len,
|
int len,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// C function `init_sdk`.
|
/// C function `init_sdk`.
|
||||||
int init_sdk(
|
int init_sdk(
|
||||||
@ -111,11 +110,12 @@ typedef _store_dart_post_cobject_Dart = void Function(
|
|||||||
bool is_tester() {
|
bool is_tester() {
|
||||||
if (Foundation.kDebugMode) {
|
if (Foundation.kDebugMode) {
|
||||||
// ignore: unnecessary_null_comparison
|
// ignore: unnecessary_null_comparison
|
||||||
if (Platform.executable == null) {
|
// if (Platform.executable.isEmpty) {
|
||||||
return false;
|
// return false;
|
||||||
} else {
|
// } else {
|
||||||
return Platform.executable.contains("tester");
|
// return Platform.executable.contains("tester");
|
||||||
}
|
// }
|
||||||
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import 'dart:io';
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
|
import 'ffi/adaptor.dart';
|
||||||
import 'ffi/ffi.dart' as ffi;
|
import 'ffi/ffi.dart' as ffi;
|
||||||
import 'package:ffi/ffi.dart';
|
import 'package:ffi/ffi.dart';
|
||||||
|
|
||||||
@ -16,12 +17,13 @@ class FlowySDK {
|
|||||||
|
|
||||||
const FlowySDK();
|
const FlowySDK();
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> init(Directory sdkDir) async {
|
Future<void> init(Directory sdkDir) async {
|
||||||
ffi.store_dart_post_cobject(NativeApi.postCObject);
|
ffi.store_dart_post_cobject(NativeApi.postCObject);
|
||||||
|
|
||||||
ffi.init_sdk(sdkDir.path.toNativeUtf8());
|
ffi.init_sdk(sdkDir.path.toNativeUtf8());
|
||||||
|
final resp = await FFIAdaptor.asyncRequest();
|
||||||
|
print(resp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,4 +8,6 @@ int64_t init_sdk(char *path);
|
|||||||
|
|
||||||
void async_command(int64_t port, const uint8_t *input, uintptr_t len);
|
void async_command(int64_t port, const uint8_t *input, uintptr_t len);
|
||||||
|
|
||||||
|
const uint8_t *sync_command(const uint8_t *input, uintptr_t len);
|
||||||
|
|
||||||
void link_me_please(void);
|
void link_me_please(void);
|
@ -204,13 +204,6 @@ packages:
|
|||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "0.0.1"
|
version: "0.0.1"
|
||||||
flowy_protobuf:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
path: "../flowy_protobuf"
|
|
||||||
relative: true
|
|
||||||
source: path
|
|
||||||
version: "0.0.1"
|
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -354,13 +347,6 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.0"
|
version: "1.5.0"
|
||||||
protobuf:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: protobuf
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.0"
|
|
||||||
pub_semver:
|
pub_semver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -16,8 +16,6 @@ dependencies:
|
|||||||
isolates: ^3.0.3+8
|
isolates: ^3.0.3+8
|
||||||
flowy_logger:
|
flowy_logger:
|
||||||
path: ../flowy_logger
|
path: ../flowy_logger
|
||||||
flowy_protobuf:
|
|
||||||
path: ../flowy_protobuf
|
|
||||||
infra:
|
infra:
|
||||||
path: ../infra
|
path: ../infra
|
||||||
dartz: '0.10.0-nullsafety.2'
|
dartz: '0.10.0-nullsafety.2'
|
||||||
|
@ -232,13 +232,6 @@ packages:
|
|||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "0.0.1"
|
version: "0.0.1"
|
||||||
flowy_protobuf:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
path: "packages/flowy_protobuf"
|
|
||||||
relative: true
|
|
||||||
source: path
|
|
||||||
version: "0.0.1"
|
|
||||||
flowy_sdk:
|
flowy_sdk:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -501,13 +494,6 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.1"
|
version: "4.2.1"
|
||||||
protobuf:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: protobuf
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.0"
|
|
||||||
provider:
|
provider:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -31,8 +31,6 @@ dependencies:
|
|||||||
sdk: flutter
|
sdk: flutter
|
||||||
flowy_sdk:
|
flowy_sdk:
|
||||||
path: packages/flowy_sdk
|
path: packages/flowy_sdk
|
||||||
flowy_protobuf:
|
|
||||||
path: packages/flowy_protobuf
|
|
||||||
flowy_style:
|
flowy_style:
|
||||||
path: packages/flowy_style
|
path: packages/flowy_style
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ byteorder = {version = "1.3.4"}
|
|||||||
ffi-support = {version = "0.4.2"}
|
ffi-support = {version = "0.4.2"}
|
||||||
protobuf = {version = "2.20.0"}
|
protobuf = {version = "2.20.0"}
|
||||||
lazy_static = {version = "1.4.0"}
|
lazy_static = {version = "1.4.0"}
|
||||||
tokio = { version = "1", features = ["sync"] }
|
tokio = { version = "1", features = ["rt", "rt-multi-thread"] }
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = {version = "1.0"}
|
serde_json = {version = "1.0"}
|
||||||
|
@ -3,50 +3,50 @@ mod c;
|
|||||||
use crate::c::forget_rust;
|
use crate::c::forget_rust;
|
||||||
use flowy_sdk::*;
|
use flowy_sdk::*;
|
||||||
use flowy_sys::prelude::*;
|
use flowy_sys::prelude::*;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
use std::{cell::RefCell, ffi::CStr, future::Future, os::raw::c_char};
|
use std::{cell::RefCell, ffi::CStr, future::Future, os::raw::c_char};
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref FFI_RUNTIME: tokio::runtime::Runtime =
|
||||||
|
tokio::runtime::Builder::new_current_thread()
|
||||||
|
.thread_name("flowy-dart-ffi")
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn init_sdk(path: *mut c_char) -> i64 {
|
pub extern "C" fn init_sdk(path: *mut c_char) -> i64 {
|
||||||
let c_str: &CStr = unsafe { CStr::from_ptr(path) };
|
let c_str: &CStr = unsafe { CStr::from_ptr(path) };
|
||||||
let path: &str = c_str.to_str().unwrap();
|
let path: &str = c_str.to_str().unwrap();
|
||||||
FlowySDK::init_log();
|
FlowySDK::init_log(path);
|
||||||
FlowySDK::init(path);
|
FlowySDK::init(path);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Deserialize)]
|
|
||||||
pub struct FFICommand {
|
|
||||||
event: String,
|
|
||||||
payload: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FFICommand {
|
|
||||||
pub fn from_bytes(bytes: Vec<u8>) -> Self {
|
|
||||||
let command: FFICommand = serde_json::from_slice(&bytes).unwrap();
|
|
||||||
command
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_u8_pointer(pointer: *const u8, len: usize) -> Self {
|
|
||||||
let bytes = unsafe { std::slice::from_raw_parts(pointer, len) }.to_vec();
|
|
||||||
FFICommand::from_bytes(bytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) {
|
pub extern "C" fn async_command(port: i64, input: *const u8, len: usize) {
|
||||||
let FFICommand { event, payload } = FFICommand::from_u8_pointer(input, len);
|
let FFICommand { event, payload } = FFICommand::from_u8_pointer(input, len);
|
||||||
log::info!("Event: {:?}", event);
|
let mut request = DispatchRequest::new(event);
|
||||||
|
log::trace!(
|
||||||
let mut request = DispatchRequest::new(port, event).callback(|_, resp| {
|
"[FFI]: {} Async Event: {:?} with {} port",
|
||||||
log::info!("async resp: {:?}", resp);
|
&request.id,
|
||||||
});
|
&request.event,
|
||||||
|
port
|
||||||
|
);
|
||||||
if !payload.is_empty() {
|
if !payload.is_empty() {
|
||||||
request = request.payload(Payload::Bytes(payload));
|
request = request.payload(Payload::Bytes(payload));
|
||||||
}
|
}
|
||||||
|
|
||||||
async_send(request);
|
request = request.callback(Box::new(move |resp: EventResponse| {
|
||||||
spawn_future(async { vec![] }, 123);
|
let bytes = match resp.data {
|
||||||
|
ResponseData::Bytes(bytes) => bytes,
|
||||||
|
ResponseData::None => vec![],
|
||||||
|
};
|
||||||
|
log::trace!("[FFI]: Post data to dart through {} port", port);
|
||||||
|
Box::pin(spawn_future(async { bytes }, port))
|
||||||
|
}));
|
||||||
|
|
||||||
|
let _ = EventDispatch::async_send(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@ -56,19 +56,36 @@ pub extern "C" fn sync_command(input: *const u8, len: usize) -> *const u8 { unim
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn link_me_please() {}
|
pub extern "C" fn link_me_please() {}
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize)]
|
||||||
|
pub struct FFICommand {
|
||||||
|
event: String,
|
||||||
|
payload: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FFICommand {
|
||||||
|
pub fn from_u8_pointer(pointer: *const u8, len: usize) -> Self {
|
||||||
|
let bytes = unsafe { std::slice::from_raw_parts(pointer, len) }.to_vec();
|
||||||
|
let command: FFICommand = serde_json::from_slice(&bytes).unwrap();
|
||||||
|
command
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn spawn_future<F>(future: F, port: i64)
|
async fn spawn_future<F>(future: F, port: i64)
|
||||||
where
|
where
|
||||||
F: Future<Output = Vec<u8>> + Send + 'static,
|
F: Future<Output = Vec<u8>> + Send + 'static,
|
||||||
{
|
{
|
||||||
let isolate = allo_isolate::Isolate::new(port);
|
let isolate = allo_isolate::Isolate::new(port);
|
||||||
isolate.catch_unwind(future);
|
match isolate.catch_unwind(future).await {
|
||||||
|
Ok(success) => {
|
||||||
// if let Err(e) = isolate.catch_unwind(future) {
|
log::trace!("[FFI]: Post data to dart success");
|
||||||
// if let Some(msg) = e.downcast_ref::<&str>() {
|
},
|
||||||
// log::error!("🔥 {:?}", msg);
|
Err(e) => {
|
||||||
// } else {
|
if let Some(msg) = e.downcast_ref::<&str>() {
|
||||||
// log::error!("no info provided for that panic 😡");
|
log::error!("[FFI]: ❌ {:?}", msg);
|
||||||
// }
|
} else {
|
||||||
// }
|
log::error!("[FFI]: allo_isolate post panic");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -262,7 +262,7 @@ pub struct ASTEnumAttrVariant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ASTEnumAttrVariant {
|
impl ASTEnumAttrVariant {
|
||||||
pub fn from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self {
|
pub fn from_ast(_cx: &Ctxt, variant: &syn::Variant) -> Self {
|
||||||
let name = variant.ident.to_string();
|
let name = variant.ident.to_string();
|
||||||
let mut value = String::new();
|
let mut value = String::new();
|
||||||
if variant.discriminant.is_some() {
|
if variant.discriminant.is_some() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::Ctxt;
|
|
||||||
use quote::format_ident;
|
|
||||||
use syn::{self, AngleBracketedGenericArguments, PathSegment};
|
use syn::{self, AngleBracketedGenericArguments, PathSegment};
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Debug)]
|
#[derive(Eq, PartialEq, Debug)]
|
||||||
|
@ -6,8 +6,9 @@ edition = "2018"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tracing = { version = "0.1" }
|
#tracing = { version = "0.1" }
|
||||||
tracing-log = { version = "0.1.1", features = ["env_logger"]}
|
tracing = { version = "0.1", features = ["max_level_debug", "release_max_level_warn"] }
|
||||||
|
tracing-log = { version = "0.1.1"}
|
||||||
tracing-futures = "0.2.4"
|
tracing-futures = "0.2.4"
|
||||||
tracing-subscriber = { version = "0.2.12", features = ["registry", "env-filter"] }
|
tracing-subscriber = { version = "0.2.12", features = ["registry", "env-filter"] }
|
||||||
tracing-bunyan-formatter = "0.2.2"
|
tracing-bunyan-formatter = "0.2.2"
|
||||||
|
@ -1,37 +1,96 @@
|
|||||||
use tracing::subscriber::set_global_default;
|
use log::LevelFilter;
|
||||||
|
use std::path::Path;
|
||||||
|
use tracing::{subscriber::set_global_default, Level};
|
||||||
|
use tracing_appender::rolling::RollingFileAppender;
|
||||||
use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer};
|
use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer};
|
||||||
use tracing_log::LogTracer;
|
use tracing_log::LogTracer;
|
||||||
use tracing_subscriber::{layer::SubscriberExt, EnvFilter};
|
use tracing_subscriber::{
|
||||||
|
layer::{Layered, SubscriberExt},
|
||||||
|
EnvFilter,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn init_log(name: &str, env_filter: &str) -> std::result::Result<(), String> {
|
pub struct FlowyLogBuilder {
|
||||||
let env_filter =
|
name: String,
|
||||||
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(env_filter.to_owned()));
|
env_filter: String,
|
||||||
let formatting_layer = BunyanFormattingLayer::new(name.to_owned(), std::io::stdout);
|
directory: String,
|
||||||
|
file_appender: RollingFileAppender,
|
||||||
|
}
|
||||||
|
|
||||||
let subscriber = tracing_subscriber::fmt()
|
impl FlowyLogBuilder {
|
||||||
.with_target(false)
|
pub fn new(name: &str, directory: impl AsRef<Path>) -> Self {
|
||||||
.with_writer(std::io::stdout)
|
let directory = directory.as_ref().to_str().unwrap().to_owned();
|
||||||
.with_thread_ids(false)
|
let local_file_name = format!("{}.log", name);
|
||||||
.with_target(false)
|
let file_appender = tracing_appender::rolling::hourly(directory.clone(), local_file_name);
|
||||||
.compact()
|
FlowyLogBuilder {
|
||||||
.finish()
|
name: name.to_owned(),
|
||||||
.with(env_filter)
|
env_filter: "Info".to_owned(),
|
||||||
.with(JsonStorageLayer)
|
directory,
|
||||||
.with(formatting_layer);
|
file_appender,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let _ = LogTracer::init().map_err(|e| format!("{:?}", e))?;
|
pub fn env_filter(mut self, env_filter: &str) -> Self {
|
||||||
let _ = set_global_default(subscriber).map_err(|e| format!("{:?}", e))?;
|
self.env_filter = env_filter.to_owned();
|
||||||
Ok(())
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(self) -> std::result::Result<(), String> {
|
||||||
|
let env_filter = EnvFilter::new(self.env_filter);
|
||||||
|
|
||||||
|
let (non_blocking, _guard) = tracing_appender::non_blocking(self.file_appender);
|
||||||
|
|
||||||
|
let formatting_layer = BunyanFormattingLayer::new(self.name, std::io::stdout);
|
||||||
|
|
||||||
|
let mut subscriber = tracing_subscriber::fmt()
|
||||||
|
.with_target(false)
|
||||||
|
.with_max_level(tracing::Level::TRACE)
|
||||||
|
.with_writer(std::io::stdout)
|
||||||
|
.with_thread_ids(false)
|
||||||
|
.with_target(false)
|
||||||
|
// .with_writer(non_blocking)
|
||||||
|
.compact()
|
||||||
|
.finish()
|
||||||
|
.with(env_filter)
|
||||||
|
.with(JsonStorageLayer)
|
||||||
|
.with(formatting_layer);
|
||||||
|
|
||||||
|
let _ = LogTracer::builder()
|
||||||
|
.with_max_level(LevelFilter::Trace)
|
||||||
|
.init()
|
||||||
|
.map_err(|e| format!("{:?}", e))
|
||||||
|
.unwrap();
|
||||||
|
let _ = set_global_default(subscriber).map_err(|e| format!("{:?}", e))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_log(name: &str, directory: &str, env_filter: &str) -> std::result::Result<(), String> {
|
||||||
|
FlowyLogBuilder::new(name, directory)
|
||||||
|
.env_filter(env_filter)
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Position {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_log() {
|
fn test_log() {
|
||||||
init_log("flowy-log", "info").unwrap();
|
init_log("flowy", ".", "Debug").unwrap();
|
||||||
tracing::info!("😁 Tracing info log");
|
tracing::info!("😁 Tracing info log");
|
||||||
log::info!("😁 bridge 'log' to 'tracing'");
|
|
||||||
|
let pos = Position {
|
||||||
|
x: 3.234,
|
||||||
|
y: -1.223,
|
||||||
|
};
|
||||||
|
|
||||||
|
tracing::debug!(?pos.x, ?pos.y);
|
||||||
|
log::debug!("😁 bridge 'log' to 'tracing'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
rust-lib/flowy-sdk/.gitignore
vendored
Normal file
12
rust-lib/flowy-sdk/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Generated by Cargo
|
||||||
|
# will have compiled files and executables
|
||||||
|
/target/
|
||||||
|
|
||||||
|
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||||
|
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||||
|
Cargo.lock
|
||||||
|
|
||||||
|
# These are backup files generated by rustfmt
|
||||||
|
**/*.rs.bk
|
||||||
|
|
||||||
|
**/temp/
|
@ -6,10 +6,10 @@ edition = "2018"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
flowy-sys = { path = "../flowy-sys" }
|
flowy-sys = { path = "../flowy-sys", features = ["use_tracing"]}
|
||||||
flowy-log = { path = "../flowy-log" }
|
flowy-log = { path = "../flowy-log" }
|
||||||
flowy-user = { path = "../flowy-user" }
|
flowy-user = { path = "../flowy-user" }
|
||||||
|
tracing = { version = "0.1" }
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
@ -6,19 +6,17 @@ use module::build_modules;
|
|||||||
pub struct FlowySDK {}
|
pub struct FlowySDK {}
|
||||||
|
|
||||||
impl FlowySDK {
|
impl FlowySDK {
|
||||||
pub fn init_log() { flowy_log::init_log("flowy", "Debug").unwrap(); }
|
pub fn init_log(directory: &str) { flowy_log::init_log("flowy", directory, "Debug").unwrap(); }
|
||||||
|
|
||||||
pub fn init(path: &str) {
|
pub fn init(path: &str) {
|
||||||
log::info!("🔥 System start running");
|
log::info!("🔥 Start running");
|
||||||
log::debug!("🔥 Root path: {}", path);
|
tracing::info!("🔥 Root path: {}", path);
|
||||||
EventDispatch::construct(|| build_modules());
|
EventDispatch::construct(|| build_modules());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn async_send(data: DispatchRequest<i64>) -> Result<EventResponse, SystemError> {
|
pub async fn async_send(request: DispatchRequest) -> EventResponse {
|
||||||
EventDispatch::async_send(data).await
|
EventDispatch::async_send(request).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sync_send(data: DispatchRequest<i64>) -> Result<EventResponse, SystemError> {
|
pub fn sync_send(request: DispatchRequest) -> EventResponse { EventDispatch::sync_send(request) }
|
||||||
EventDispatch::sync_send(data)
|
|
||||||
}
|
|
||||||
|
@ -3,32 +3,42 @@ pub use flowy_sdk::*;
|
|||||||
use flowy_sys::prelude::*;
|
use flowy_sys::prelude::*;
|
||||||
use std::{
|
use std::{
|
||||||
fmt::{Debug, Display},
|
fmt::{Debug, Display},
|
||||||
|
fs,
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
sync::Once,
|
sync::Once,
|
||||||
};
|
};
|
||||||
|
|
||||||
static INIT: Once = Once::new();
|
static INIT: Once = Once::new();
|
||||||
#[allow(dead_code)]
|
pub fn init_sdk() {
|
||||||
|
let root_dir = root_dir();
|
||||||
|
|
||||||
pub fn init_system() {
|
|
||||||
INIT.call_once(|| {
|
INIT.call_once(|| {
|
||||||
FlowySDK::init_log();
|
FlowySDK::init_log(&root_dir);
|
||||||
});
|
});
|
||||||
|
FlowySDK::init(&root_dir);
|
||||||
FlowySDK::init("123");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FlowySDKTester {
|
fn root_dir() -> String {
|
||||||
request: DispatchRequest<i64>,
|
let mut path = fs::canonicalize(".").unwrap();
|
||||||
|
path.push("tests/temp/flowy/");
|
||||||
|
let path_str = path.to_str().unwrap().to_string();
|
||||||
|
if !std::path::Path::new(&path).exists() {
|
||||||
|
std::fs::create_dir_all(path).unwrap();
|
||||||
|
}
|
||||||
|
path_str
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlowySDKTester {
|
pub struct EventTester {
|
||||||
|
request: DispatchRequest,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventTester {
|
||||||
pub fn new<E>(event: E) -> Self
|
pub fn new<E>(event: E) -> Self
|
||||||
where
|
where
|
||||||
E: Eq + Hash + Debug + Clone + Display,
|
E: Eq + Hash + Debug + Clone + Display,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
request: DispatchRequest::new(1, event),
|
request: DispatchRequest::new(event),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,16 +62,18 @@ impl FlowySDKTester {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub async fn async_send(self) -> EventResponse {
|
pub async fn async_send(self) -> EventResponse {
|
||||||
init_system();
|
init_sdk();
|
||||||
let resp = async_send(self.request).await.unwrap();
|
let resp = async_send(self.request).await;
|
||||||
dbg!(&resp);
|
dbg!(&resp);
|
||||||
resp
|
resp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn sync_send(self) -> EventResponse {
|
pub fn sync_send(self) -> EventResponse {
|
||||||
init_system();
|
init_sdk();
|
||||||
let resp = sync_send(self.request).unwrap();
|
let resp = sync_send(self.request);
|
||||||
dbg!(&resp);
|
dbg!(&resp);
|
||||||
resp
|
resp
|
||||||
}
|
}
|
||||||
|
@ -4,19 +4,17 @@ use flowy_user::prelude::*;
|
|||||||
use tokio::time::{sleep, Duration};
|
use tokio::time::{sleep, Duration};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
fn auth_check_no_payload() {
|
fn auth_check_no_payload() {
|
||||||
let callback = |_, resp: EventResponse| {
|
let resp = EventTester::new(AuthCheck).sync_send();
|
||||||
assert_eq!(resp.status, StatusCode::Err);
|
assert_eq!(resp.status, StatusCode::Ok);
|
||||||
};
|
|
||||||
|
|
||||||
let resp = FlowySDKTester::new(AuthCheck).sync_send();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn auth_check_with_user_name_email_payload() {
|
async fn auth_check_with_user_name_email_payload() {
|
||||||
let user_data = UserData::new("jack".to_owned(), "helloworld@gmail.com".to_owned());
|
let user_data = UserData::new("jack".to_owned(), "helloworld@gmail.com".to_owned());
|
||||||
|
|
||||||
FlowySDKTester::new(AuthCheck)
|
EventTester::new(AuthCheck)
|
||||||
.bytes_payload(user_data)
|
.bytes_payload(user_data)
|
||||||
.sync_send();
|
.sync_send();
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ serde = { version = "1.0", features = ["derive"] }
|
|||||||
#optional crate
|
#optional crate
|
||||||
bincode = { version = "1.3", optional = true}
|
bincode = { version = "1.3", optional = true}
|
||||||
protobuf = {version = "2.24.1", optional = true}
|
protobuf = {version = "2.24.1", optional = true}
|
||||||
|
tracing = { version = "0.1", optional = true}
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
@ -36,3 +37,4 @@ futures-util = "0.3.15"
|
|||||||
[features]
|
[features]
|
||||||
use_serde = ["bincode"]
|
use_serde = ["bincode"]
|
||||||
use_protobuf= ["protobuf"]
|
use_protobuf= ["protobuf"]
|
||||||
|
use_tracing= ["tracing"]
|
||||||
|
@ -8,11 +8,19 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use derivative::*;
|
use derivative::*;
|
||||||
use futures_core::future::BoxFuture;
|
use futures_core::future::BoxFuture;
|
||||||
|
use futures_util::task::Context;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
use pin_project::pin_project;
|
||||||
use std::{
|
use std::{
|
||||||
fmt::{Debug, Display},
|
fmt::{Debug, Display},
|
||||||
|
future::Future,
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
sync::RwLock,
|
sync::RwLock,
|
||||||
|
thread::JoinHandle,
|
||||||
|
};
|
||||||
|
use tokio::{
|
||||||
|
macros::support::{Pin, Poll},
|
||||||
|
task::JoinError,
|
||||||
};
|
};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
@ -30,9 +38,9 @@ impl EventDispatch {
|
|||||||
F: FnOnce() -> Vec<Module>,
|
F: FnOnce() -> Vec<Module>,
|
||||||
{
|
{
|
||||||
let modules = module_factory();
|
let modules = module_factory();
|
||||||
|
log::debug!("{}", module_info(&modules));
|
||||||
let module_map = as_module_map(modules);
|
let module_map = as_module_map(modules);
|
||||||
let runtime = tokio_default_runtime().unwrap();
|
let runtime = tokio_default_runtime().unwrap();
|
||||||
|
|
||||||
let dispatch = EventDispatch {
|
let dispatch = EventDispatch {
|
||||||
module_map,
|
module_map,
|
||||||
runtime,
|
runtime,
|
||||||
@ -41,115 +49,133 @@ impl EventDispatch {
|
|||||||
*(EVENT_DISPATCH.write().unwrap()) = Some(dispatch);
|
*(EVENT_DISPATCH.write().unwrap()) = Some(dispatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn async_send<T>(request: DispatchRequest<T>) -> Result<EventResponse, SystemError>
|
pub fn async_send(request: DispatchRequest) -> DispatchFuture {
|
||||||
where
|
|
||||||
T: 'static + Debug + Send + Sync,
|
|
||||||
{
|
|
||||||
match EVENT_DISPATCH.read() {
|
match EVENT_DISPATCH.read() {
|
||||||
Ok(dispatch) => {
|
Ok(dispatch) => {
|
||||||
let dispatch = dispatch.as_ref().unwrap();
|
let dispatch = dispatch.as_ref().unwrap();
|
||||||
let module_map = dispatch.module_map.clone();
|
let module_map = dispatch.module_map.clone();
|
||||||
let service = Box::new(DispatchService { module_map });
|
let service = Box::new(DispatchService { module_map });
|
||||||
dispatch
|
log::trace!("{}: dispatch {:?} to runtime", &request.id, &request.event);
|
||||||
.runtime
|
let join_handle = dispatch.runtime.spawn(async move {
|
||||||
.spawn(async move { service.call(request).await })
|
service
|
||||||
.await
|
.call(request)
|
||||||
.unwrap_or_else(|e| {
|
.await
|
||||||
let msg = format!("{:?}", e);
|
.unwrap_or_else(|e| InternalError::new(format!("{:?}", e)).as_response())
|
||||||
Ok(InternalError::new(msg).as_response())
|
});
|
||||||
})
|
|
||||||
|
DispatchFuture {
|
||||||
|
fut: Box::pin(async move {
|
||||||
|
join_handle.await.unwrap_or_else(|e| {
|
||||||
|
InternalError::new(format!("Dispatch join error: {:?}", e))
|
||||||
|
.as_response()
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let msg = format!("{:?}", e);
|
let msg = format!("Dispatch runtime error: {:?}", e);
|
||||||
Err(InternalError::new(msg).into())
|
log::trace!("{}", msg);
|
||||||
|
DispatchFuture {
|
||||||
|
fut: Box::pin(async { InternalError::new(msg).as_response() }),
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sync_send<T>(request: DispatchRequest<T>) -> Result<EventResponse, SystemError>
|
pub fn sync_send(request: DispatchRequest) -> EventResponse {
|
||||||
where
|
|
||||||
T: 'static + Debug + Send + Sync,
|
|
||||||
{
|
|
||||||
futures::executor::block_on(async { EventDispatch::async_send(request).await })
|
futures::executor::block_on(async { EventDispatch::async_send(request).await })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type BoxStreamCallback<T> = Box<dyn FnOnce(T, EventResponse) + 'static + Send + Sync>;
|
#[pin_project]
|
||||||
|
pub struct DispatchFuture {
|
||||||
|
#[pin]
|
||||||
|
fut: BoxFuture<'static, EventResponse>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Future for DispatchFuture {
|
||||||
|
type Output = EventResponse;
|
||||||
|
|
||||||
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
|
let this = self.as_mut().project();
|
||||||
|
loop {
|
||||||
|
return Poll::Ready(futures_core::ready!(this.fut.poll(cx)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type BoxFutureCallback =
|
||||||
|
Box<dyn FnOnce(EventResponse) -> BoxFuture<'static, ()> + 'static + Send + Sync>;
|
||||||
|
|
||||||
#[derive(Derivative)]
|
#[derive(Derivative)]
|
||||||
#[derivative(Debug)]
|
#[derivative(Debug)]
|
||||||
pub struct DispatchRequest<T>
|
pub struct DispatchRequest {
|
||||||
where
|
pub id: String,
|
||||||
T: 'static + Debug,
|
|
||||||
{
|
|
||||||
pub config: T,
|
|
||||||
pub event: Event,
|
pub event: Event,
|
||||||
pub payload: Option<Payload>,
|
pub payload: Payload,
|
||||||
#[derivative(Debug = "ignore")]
|
#[derivative(Debug = "ignore")]
|
||||||
pub callback: Option<BoxStreamCallback<T>>,
|
pub callback: Option<BoxFutureCallback>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> DispatchRequest<T>
|
impl DispatchRequest {
|
||||||
where
|
pub fn new<E>(event: E) -> Self
|
||||||
T: 'static + Debug,
|
|
||||||
{
|
|
||||||
pub fn new<E>(config: T, event: E) -> Self
|
|
||||||
where
|
where
|
||||||
E: Eq + Hash + Debug + Clone + Display,
|
E: Eq + Hash + Debug + Clone + Display,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
config,
|
payload: Payload::None,
|
||||||
payload: None,
|
|
||||||
event: event.into(),
|
event: event.into(),
|
||||||
|
id: uuid::Uuid::new_v4().to_string(),
|
||||||
callback: None,
|
callback: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn payload(mut self, payload: Payload) -> Self {
|
pub fn payload(mut self, payload: Payload) -> Self {
|
||||||
self.payload = Some(payload);
|
self.payload = payload;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn callback<F>(mut self, callback: F) -> Self
|
pub fn callback(mut self, callback: BoxFutureCallback) -> Self {
|
||||||
where
|
self.callback = Some(callback);
|
||||||
F: FnOnce(T, EventResponse) + 'static + Send + Sync,
|
|
||||||
{
|
|
||||||
self.callback = Some(Box::new(callback));
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn into_parts(self) -> (ModuleRequest, Option<BoxFutureCallback>) {
|
||||||
|
let DispatchRequest {
|
||||||
|
event,
|
||||||
|
payload,
|
||||||
|
id,
|
||||||
|
callback,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
(ModuleRequest::new(event.clone(), id, payload), callback)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct DispatchService {
|
pub(crate) struct DispatchService {
|
||||||
pub(crate) module_map: ModuleMap,
|
pub(crate) module_map: ModuleMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Service<DispatchRequest<T>> for DispatchService
|
impl Service<DispatchRequest> for DispatchService {
|
||||||
where
|
|
||||||
T: 'static + Debug + Send + Sync,
|
|
||||||
{
|
|
||||||
type Response = EventResponse;
|
type Response = EventResponse;
|
||||||
type Error = SystemError;
|
type Error = SystemError;
|
||||||
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
|
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
|
||||||
|
|
||||||
fn call(&self, dispatch_request: DispatchRequest<T>) -> Self::Future {
|
fn call(&self, dispatch_request: DispatchRequest) -> Self::Future {
|
||||||
let module_map = self.module_map.clone();
|
let module_map = self.module_map.clone();
|
||||||
let DispatchRequest {
|
let (request, callback) = dispatch_request.into_parts();
|
||||||
config,
|
|
||||||
event,
|
|
||||||
payload,
|
|
||||||
callback,
|
|
||||||
} = dispatch_request;
|
|
||||||
|
|
||||||
let mut request = ModuleRequest::new(event.clone());
|
|
||||||
if let Some(payload) = payload {
|
|
||||||
request = request.payload(payload);
|
|
||||||
};
|
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let result = {
|
let result = {
|
||||||
match module_map.get(&event) {
|
match module_map.get(&request.event()) {
|
||||||
Some(module) => {
|
Some(module) => {
|
||||||
let fut = module.new_service(());
|
let fut = module.new_service(());
|
||||||
|
log::trace!(
|
||||||
|
"{}: handle event: {:?} by {}",
|
||||||
|
request.id(),
|
||||||
|
request.event(),
|
||||||
|
module.name
|
||||||
|
);
|
||||||
let service_fut = fut.await?.call(request);
|
let service_fut = fut.await?.call(request);
|
||||||
service_fut.await
|
service_fut.await
|
||||||
},
|
},
|
||||||
@ -158,17 +184,27 @@ where
|
|||||||
"Can not find the module to handle the request:{:?}",
|
"Can not find the module to handle the request:{:?}",
|
||||||
request
|
request
|
||||||
);
|
);
|
||||||
|
log::trace!("{}", msg);
|
||||||
Err(InternalError::new(msg).into())
|
Err(InternalError::new(msg).into())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = result.unwrap_or_else(|e| e.into());
|
let response = result.unwrap_or_else(|e| e.into());
|
||||||
|
log::trace!("Dispatch result: {:?}", response);
|
||||||
if let Some(callback) = callback {
|
if let Some(callback) = callback {
|
||||||
callback(config, response.clone());
|
callback(response.clone()).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(response)
|
Ok(response)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn module_info(modules: &Vec<Module>) -> String {
|
||||||
|
let mut info = format!("{} modules loaded\n", modules.len());
|
||||||
|
for module in modules {
|
||||||
|
info.push_str(&format!("-> {} loaded \n", module.name));
|
||||||
|
}
|
||||||
|
info
|
||||||
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
|
fmt,
|
||||||
fmt::{Debug, Display},
|
fmt::{Debug, Display},
|
||||||
future::Future,
|
future::Future,
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
@ -53,7 +54,7 @@ impl<T: Display + Eq + Hash + Debug + Clone> std::convert::From<T> for Event {
|
|||||||
pub type EventServiceFactory = BoxServiceFactory<(), ServiceRequest, ServiceResponse, SystemError>;
|
pub type EventServiceFactory = BoxServiceFactory<(), ServiceRequest, ServiceResponse, SystemError>;
|
||||||
|
|
||||||
pub struct Module {
|
pub struct Module {
|
||||||
name: String,
|
pub name: String,
|
||||||
data: DataContainer,
|
data: DataContainer,
|
||||||
service_map: Arc<HashMap<Event, EventServiceFactory>>,
|
service_map: Arc<HashMap<Event, EventServiceFactory>>,
|
||||||
}
|
}
|
||||||
@ -112,26 +113,27 @@ pub struct ModuleRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleRequest {
|
impl ModuleRequest {
|
||||||
pub fn new<E>(event: E) -> Self
|
pub fn new<E>(event: E, id: String, payload: Payload) -> Self
|
||||||
where
|
where
|
||||||
E: Into<Event>,
|
E: Into<Event>,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
inner: EventRequest::new(event),
|
inner: EventRequest::new(event, id),
|
||||||
payload: Payload::None,
|
payload,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn payload(mut self, payload: Payload) -> Self {
|
|
||||||
self.payload = payload;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn id(&self) -> &str { &self.inner.id }
|
pub(crate) fn id(&self) -> &str { &self.inner.id }
|
||||||
|
|
||||||
pub(crate) fn event(&self) -> &Event { &self.inner.event }
|
pub(crate) fn event(&self) -> &Event { &self.inner.event }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for ModuleRequest {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "{}:{:?}", self.inner.id, self.inner.event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl std::convert::Into<ServiceRequest> for ModuleRequest {
|
impl std::convert::Into<ServiceRequest> for ModuleRequest {
|
||||||
fn into(self) -> ServiceRequest { ServiceRequest::new(self.inner, self.payload) }
|
fn into(self) -> ServiceRequest { ServiceRequest::new(self.inner, self.payload) }
|
||||||
}
|
}
|
||||||
@ -162,8 +164,9 @@ impl Service<ModuleRequest> for ModuleService {
|
|||||||
type Error = SystemError;
|
type Error = SystemError;
|
||||||
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
|
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
|
||||||
|
|
||||||
|
// #[cfg_attr(feature = "use_tracing", xxx)]
|
||||||
|
#[tracing::instrument(name = "Module Service", level = "debug", skip(self))]
|
||||||
fn call(&self, request: ModuleRequest) -> Self::Future {
|
fn call(&self, request: ModuleRequest) -> Self::Future {
|
||||||
log::trace!("Call module service for request {}", &request.id());
|
|
||||||
match self.service_map.get(&request.event()) {
|
match self.service_map.get(&request.event()) {
|
||||||
Some(factory) => {
|
Some(factory) => {
|
||||||
let service_fut = factory.new_service(());
|
let service_fut = factory.new_service(());
|
||||||
|
@ -7,7 +7,6 @@ use crate::{
|
|||||||
util::ready::{ready, Ready},
|
util::ready::{ready, Ready},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
use futures_core::ready;
|
use futures_core::ready;
|
||||||
use std::{
|
use std::{
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
@ -23,12 +22,12 @@ pub struct EventRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl EventRequest {
|
impl EventRequest {
|
||||||
pub fn new<E>(event: E) -> EventRequest
|
pub fn new<E>(event: E, id: String) -> EventRequest
|
||||||
where
|
where
|
||||||
E: Into<Event>,
|
E: Into<Event>,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
id: uuid::Uuid::new_v4().to_string(),
|
id,
|
||||||
event: event.into(),
|
event: event.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,11 +62,8 @@ impl FromRequest for String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn unexpected_none_payload(request: &EventRequest) -> SystemError {
|
fn unexpected_none_payload(request: &EventRequest) -> SystemError {
|
||||||
log::warn!(
|
log::warn!("{:?} expected payload", &request.event);
|
||||||
"Event: {:?} expected payload but payload is empty",
|
InternalError::new("Expected payload").into()
|
||||||
&request.event
|
|
||||||
);
|
|
||||||
InternalError::new("Expected payload but payload is empty").into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
pub use builder::*;
|
pub use builder::*;
|
||||||
|
pub use data::*;
|
||||||
pub use responder::*;
|
pub use responder::*;
|
||||||
pub use response::*;
|
pub use response::*;
|
||||||
|
|
||||||
mod builder;
|
mod builder;
|
||||||
pub mod data;
|
mod data;
|
||||||
mod responder;
|
mod responder;
|
||||||
mod response;
|
mod response;
|
||||||
|
@ -6,7 +6,7 @@ pub mod ready;
|
|||||||
|
|
||||||
pub(crate) fn tokio_default_runtime() -> io::Result<tokio::runtime::Runtime> {
|
pub(crate) fn tokio_default_runtime() -> io::Result<tokio::runtime::Runtime> {
|
||||||
runtime::Builder::new_multi_thread()
|
runtime::Builder::new_multi_thread()
|
||||||
.thread_name("flowy-sys")
|
.thread_name("flowy-rt")
|
||||||
.enable_io()
|
.enable_io()
|
||||||
.enable_time()
|
.enable_time()
|
||||||
.on_thread_start(move || {
|
.on_thread_start(move || {
|
||||||
|
@ -10,14 +10,13 @@ pub fn setup_env() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn async_send(data: DispatchRequest<i64>) -> Result<EventResponse, SystemError> {
|
pub async fn async_send(request: DispatchRequest) -> EventResponse {
|
||||||
EventDispatch::async_send(data).await
|
EventDispatch::async_send(request).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_system<F>(module_factory: F)
|
pub fn init_dispatch<F>(module_factory: F)
|
||||||
where
|
where
|
||||||
F: FnOnce() -> Vec<Module>,
|
F: FnOnce() -> Vec<Module>,
|
||||||
{
|
{
|
||||||
let system = EventDispatch::new(module_factory);
|
EventDispatch::construct(module_factory);
|
||||||
EventDispatch::set_current(system);
|
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,9 @@ pub async fn hello() -> String { "say hello".to_string() }
|
|||||||
async fn test_init() {
|
async fn test_init() {
|
||||||
setup_env();
|
setup_env();
|
||||||
let event = "1";
|
let event = "1";
|
||||||
init_system(|| vec![Module::new().event(event, hello)]);
|
init_dispatch(|| vec![Module::new().event(event, hello)]);
|
||||||
|
|
||||||
let request = DispatchRequest::new(1, event);
|
let request = DispatchRequest::new(event);
|
||||||
let resp = async_send(request).await.unwrap();
|
let resp = async_send(request).await;
|
||||||
log::info!("sync resp: {:?}", resp);
|
dbg!(&resp);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ use flowy_sys::prelude::*;
|
|||||||
|
|
||||||
pub fn create() -> Module {
|
pub fn create() -> Module {
|
||||||
Module::new()
|
Module::new()
|
||||||
|
.name("Flowy-User")
|
||||||
.event(AuthCheck, user_check)
|
.event(AuthCheck, user_check)
|
||||||
.event(SignIn, user_check)
|
.event(SignIn, user_check)
|
||||||
.event(SignUp, user_check)
|
.event(SignUp, user_check)
|
||||||
|
6
scripts/build_sdk.sh
Executable file
6
scripts/build_sdk.sh
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#!/usr/bin/env fish
|
||||||
|
echo 'Start building rust sdk'
|
||||||
|
rustup show
|
||||||
|
|
||||||
|
cargo make desktop
|
Loading…
Reference in New Issue
Block a user