This commit is contained in:
John Smith 2022-02-15 13:40:17 -05:00
parent 125901fcd8
commit 7458d0d991
12 changed files with 191 additions and 103 deletions

View File

@ -357,38 +357,38 @@ impl AttachmentManager {
attachment_machine.state() attachment_machine.state()
} }
pub async fn wait_for_state(&self, state: AttachmentState, timeout_ms: Option<u32>) -> bool { // pub async fn wait_for_state(&self, state: AttachmentState, timeout_ms: Option<u32>) -> bool {
let start_time = intf::get_timestamp(); // let start_time = intf::get_timestamp();
loop { // loop {
let (current_state, eventual) = self // let (current_state, eventual) = self
.inner // .inner
.lock() // .lock()
.attachment_machine // .attachment_machine
.state_eventual_instance(); // .state_eventual_instance();
if current_state == state { // if current_state == state {
break; // break;
} // }
if let Some(timeout_ms) = timeout_ms { // if let Some(timeout_ms) = timeout_ms {
let timeout_time = start_time + (timeout_ms as u64 * 1000); // let timeout_time = start_time + (timeout_ms as u64 * 1000);
let cur_time = intf::get_timestamp(); // let cur_time = intf::get_timestamp();
if timeout_time > cur_time { // if timeout_time > cur_time {
let timeout_dur_ms = ((timeout_time - cur_time) / 1000) as u32; // let timeout_dur_ms = ((timeout_time - cur_time) / 1000) as u32;
if match intf::timeout(timeout_dur_ms, eventual).await { // if match intf::timeout(timeout_dur_ms, eventual).await {
Ok(v) => v, // Ok(v) => v,
Err(_) => return false, // Err(_) => return false,
} == state // } == state
{ // {
return true; // return true;
} // }
} else { // } else {
return false; // return false;
} // }
} else if eventual.await == state { // } else if eventual.await == state {
break; // break;
} // }
} // }
true // true
} // }
} }

View File

@ -21,6 +21,7 @@ pub struct VeilidCoreContext {
pub block_store: BlockStore, pub block_store: BlockStore,
pub crypto: Crypto, pub crypto: Crypto,
pub attachment_manager: AttachmentManager, pub attachment_manager: AttachmentManager,
pub update_callback: UpdateCallback,
} }
impl VeilidCoreContext { impl VeilidCoreContext {
@ -128,12 +129,13 @@ impl VeilidCoreContext {
// Set up attachment manager // Set up attachment manager
trace!("VeilidCoreContext::new init attachment manager"); trace!("VeilidCoreContext::new init attachment manager");
let update_callback_move = update_callback.clone();
let attachment_manager = let attachment_manager =
AttachmentManager::new(config.clone(), table_store.clone(), crypto.clone()); AttachmentManager::new(config.clone(), table_store.clone(), crypto.clone());
if let Err(e) = attachment_manager if let Err(e) = attachment_manager
.init(Arc::new( .init(Arc::new(
move |_old_state: AttachmentState, new_state: AttachmentState| { move |_old_state: AttachmentState, new_state: AttachmentState| {
update_callback(VeilidUpdate::Attachment { state: new_state }) update_callback_move(VeilidUpdate::Attachment { state: new_state })
}, },
)) ))
.await .await
@ -154,6 +156,7 @@ impl VeilidCoreContext {
block_store, block_store,
crypto, crypto,
attachment_manager, attachment_manager,
update_callback,
}) })
} }
@ -167,6 +170,9 @@ impl VeilidCoreContext {
self.protected_store.terminate().await; self.protected_store.terminate().await;
self.config.terminate().await; self.config.terminate().await;
// send final shutdown update
(self.update_callback)(VeilidUpdate::Shutdown).await;
trace!("VeilidCoreContext::shutdown complete"); trace!("VeilidCoreContext::shutdown complete");
ApiLogger::terminate(); ApiLogger::terminate();
} }

View File

@ -22,14 +22,7 @@ pub async fn test_attach_detach() {
api.attach().await.unwrap(); api.attach().await.unwrap();
intf::sleep(5000).await; intf::sleep(5000).await;
api.detach().await.unwrap(); api.detach().await.unwrap();
api.wait_for_update( intf::sleep(2000).await;
VeilidUpdate::Attachment {
state: AttachmentState::Detached,
},
None,
)
.await
.unwrap();
api.shutdown().await; api.shutdown().await;
info!("--- test auto detach ---"); info!("--- test auto detach ---");

View File

@ -168,6 +168,7 @@ pub enum VeilidUpdate {
Attachment { Attachment {
state: AttachmentState, state: AttachmentState,
}, },
Shutdown,
} }
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
@ -1216,28 +1217,6 @@ impl VeilidAPI {
Ok(()) Ok(())
} }
// wait for a matching update
pub async fn wait_for_update(
&self,
update: VeilidUpdate,
timeout_ms: Option<u32>,
) -> Result<(), VeilidAPIError> {
match update {
VeilidUpdate::Log {
log_level: _,
message: _,
} => {
// No point in waiting for a log
}
VeilidUpdate::Attachment { state } => {
self.attachment_manager()?
.wait_for_state(state, timeout_ms)
.await;
}
}
Ok(())
}
// Change api logging level if it is enabled // Change api logging level if it is enabled
pub async fn change_api_log_level(&self, log_level: VeilidConfigLogLevel) { pub async fn change_api_log_level(&self, log_level: VeilidConfigLogLevel) {
ApiLogger::change_log_level(log_level.to_level_filter()); ApiLogger::change_log_level(log_level.to_level_filter());

View File

@ -1,13 +1,54 @@
import 'dart:async'; import 'dart:async';
import 'package:logger/logger.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:veilid/veilid.dart'; import 'package:veilid/veilid.dart';
import 'package:logger_flutter_viewer/logger_flutter_viewer.dart';
// Logger
var stacklog = Logger(
printer: PrettyPrinter(
methodCount: 10,
errorMethodCount: 10,
printTime: true,
colors: true,
printEmojis: true),
output: ScreenOutput());
var log = Logger(
printer: PrettyPrinter(
methodCount: 0,
errorMethodCount: 1,
printTime: true,
colors: true,
printEmojis: true,
noBoxingByDefault: true,
),
output: ScreenOutput());
var barelog = Logger(
printer: PrettyPrinter(
methodCount: 0,
errorMethodCount: 0,
printTime: false,
colors: true,
printEmojis: true,
noBoxingByDefault: true,
),
output: ScreenOutput());
class ScreenOutput extends LogOutput {
@override
void output(OutputEvent event) {
LogConsole.output(event);
}
}
// Entrypoint
void main() { void main() {
runApp(const MyApp()); runApp(const MyApp());
} }
// Main App
class MyApp extends StatefulWidget { class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key); const MyApp({Key? key}) : super(key: key);
@ -34,6 +75,10 @@ class _MyAppState extends State<MyApp> {
} on PlatformException { } on PlatformException {
veilidVersion = 'Failed to get veilid version.'; veilidVersion = 'Failed to get veilid version.';
} }
log.e("Error test");
log.w("Warning test");
stacklog.i("Info test with stacklog");
barelog.d("debug bare-log test");
// If the widget was removed from the tree while the asynchronous platform // If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling // message was in flight, we want to discard the reply rather than calling
@ -50,11 +95,9 @@ class _MyAppState extends State<MyApp> {
return MaterialApp( return MaterialApp(
home: Scaffold( home: Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text('Veilid Plugin Example App'), title: Text('Veilid Plugin Version $_veilidVersion'),
),
body: Center(
child: Text('Veilid version: $_veilidVersion\n'),
), ),
body: LogConsole(dark: Theme.of(context).brightness == Brightness.dark),
), ),
); );
} }

View File

@ -107,6 +107,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.1" version: "1.0.1"
logger:
dependency: "direct main"
description:
name: logger
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
logger_flutter_viewer:
dependency: "direct main"
description:
name: logger_flutter_viewer
url: "https://pub.dartlang.org"
source: hosted
version: "0.8.0"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
@ -135,6 +149,34 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.0" version: "1.8.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
sensors_plus:
dependency: transitive
description:
name: sensors_plus
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
sensors_plus_platform_interface:
dependency: transitive
description:
name: sensors_plus_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
sensors_plus_web:
dependency: transitive
description:
name: sensors_plus_web
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter

View File

@ -33,6 +33,8 @@ dependencies:
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
logger: ^1.1.0
logger_flutter_viewer: ^0.8.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View File

@ -119,7 +119,14 @@ pub extern "C" fn startup_veilid_core(port: i64, config: FfiStr) {
move |update: veilid_core::VeilidUpdate| -> veilid_core::SystemPinBoxFuture<()> { move |update: veilid_core::VeilidUpdate| -> veilid_core::SystemPinBoxFuture<()> {
let sink = sink.clone(); let sink = sink.clone();
Box::pin(async move { Box::pin(async move {
sink.item_json(update); match update {
veilid_core::VeilidUpdate::Shutdown => {
sink.close();
}
_ => {
sink.item_json(update);
}
}
}) })
}, },
); );
@ -159,6 +166,16 @@ pub extern "C" fn shutdown_veilid_core(port: i64) {
}); });
} }
#[no_mangle]
pub extern "C" fn debug(port: i64, command: FfiStr) {
let command = command.into_opt_string().unwrap_or_default();
DartIsolateWrapper::new(port).spawn_result(async move {
let veilid_api = get_veilid_api().await?;
let out = veilid_api.debug(command).await?;
APIResult::Ok(out)
});
}
#[no_mangle] #[no_mangle]
pub extern "C" fn veilid_version_string() -> *mut c_char { pub extern "C" fn veilid_version_string() -> *mut c_char {
veilid_core::veilid_version_string().into_ffi_value() veilid_core::veilid_version_string().into_ffi_value()

View File

@ -13,12 +13,12 @@ pub struct DartIsolateWrapper {
} }
const MESSAGE_OK: i32 = 0; const MESSAGE_OK: i32 = 0;
const MESSAGE_ERR: i32 = 1; //const MESSAGE_ERR: i32 = 1;
const MESSAGE_OK_JSON: i32 = 2; const MESSAGE_OK_JSON: i32 = 2;
const MESSAGE_ERR_JSON: i32 = 3; const MESSAGE_ERR_JSON: i32 = 3;
const MESSAGE_STREAM_ITEM: i32 = 4; //const MESSAGE_STREAM_ITEM: i32 = 4;
const MESSAGE_STREAM_ITEM_JSON: i32 = 5; const MESSAGE_STREAM_ITEM_JSON: i32 = 5;
const MESSAGE_STREAM_ABORT: i32 = 6; //const MESSAGE_STREAM_ABORT: i32 = 6;
const MESSAGE_STREAM_ABORT_JSON: i32 = 7; const MESSAGE_STREAM_ABORT_JSON: i32 = 7;
const MESSAGE_STREAM_CLOSE: i32 = 8; const MESSAGE_STREAM_CLOSE: i32 = 8;
@ -29,6 +29,17 @@ impl DartIsolateWrapper {
} }
} }
pub fn spawn_result<F, T, E>(self, future: F)
where
F: Future<Output = Result<T, E>> + Send + 'static,
T: IntoDart,
E: Serialize,
{
async_std::task::spawn(async move {
self.result(future.await);
});
}
pub fn spawn_result_json<F, T, E>(self, future: F) pub fn spawn_result_json<F, T, E>(self, future: F)
where where
F: Future<Output = Result<T, E>> + Send + 'static, F: Future<Output = Result<T, E>> + Send + 'static,
@ -40,10 +51,10 @@ impl DartIsolateWrapper {
}); });
} }
pub fn result<T: IntoDart, E: IntoDart>(&self, result: Result<T, E>) -> bool { pub fn result<T: IntoDart, E: Serialize>(&self, result: Result<T, E>) -> bool {
match result { match result {
Ok(v) => self.ok(v), Ok(v) => self.ok(v),
Err(e) => self.err(e), Err(e) => self.err_json(e),
} }
} }
pub fn result_json<T: Serialize, E: Serialize>(&self, result: Result<T, E>) -> bool { pub fn result_json<T: Serialize, E: Serialize>(&self, result: Result<T, E>) -> bool {
@ -64,10 +75,10 @@ impl DartIsolateWrapper {
]) ])
} }
pub fn err<E: IntoDart>(&self, error: E) -> bool { // pub fn err<E: IntoDart>(&self, error: E) -> bool {
self.isolate // self.isolate
.post(vec![MESSAGE_ERR.into_dart(), error.into_dart()]) // .post(vec![MESSAGE_ERR.into_dart(), error.into_dart()])
} // }
pub fn err_json<E: Serialize>(&self, error: E) -> bool { pub fn err_json<E: Serialize>(&self, error: E) -> bool {
self.isolate.post(vec![ self.isolate.post(vec![
@ -89,14 +100,14 @@ impl DartIsolateStream {
} }
} }
pub fn item<T: IntoDart>(&self, value: T) -> bool { // pub fn item<T: IntoDart>(&self, value: T) -> bool {
let isolate = self.isolate.lock(); // let isolate = self.isolate.lock();
if let Some(isolate) = &*isolate { // if let Some(isolate) = &*isolate {
isolate.post(vec![MESSAGE_STREAM_ITEM.into_dart(), value.into_dart()]) // isolate.post(vec![MESSAGE_STREAM_ITEM.into_dart(), value.into_dart()])
} else { // } else {
false // false
} // }
} // }
pub fn item_json<T: Serialize>(&self, value: T) -> bool { pub fn item_json<T: Serialize>(&self, value: T) -> bool {
let isolate = self.isolate.lock(); let isolate = self.isolate.lock();
@ -110,14 +121,14 @@ impl DartIsolateStream {
} }
} }
pub fn abort<E: IntoDart>(self, error: E) -> bool { // pub fn abort<E: IntoDart>(self, error: E) -> bool {
let mut isolate = self.isolate.lock(); // let mut isolate = self.isolate.lock();
if let Some(isolate) = isolate.take() { // if let Some(isolate) = isolate.take() {
isolate.post(vec![MESSAGE_STREAM_ABORT.into_dart(), error.into_dart()]) // isolate.post(vec![MESSAGE_STREAM_ABORT.into_dart(), error.into_dart()])
} else { // } else {
false // false
} // }
} // }
pub fn abort_json<E: Serialize>(self, error: E) -> bool { pub fn abort_json<E: Serialize>(self, error: E) -> bool {
let mut isolate = self.isolate.lock(); let mut isolate = self.isolate.lock();

View File

@ -18,7 +18,7 @@ struct Attachment {
struct VeilidUpdate { struct VeilidUpdate {
union { union {
attachment @0 :Attachment; attachment @0 :Attachment;
dummy @1 :Void; shutdown @1 :Void;
} }
} }

View File

@ -33,7 +33,7 @@ fn convert_attachment_state(state: &veilid_core::AttachmentState) -> AttachmentS
fn convert_update( fn convert_update(
update: &veilid_core::VeilidUpdate, update: &veilid_core::VeilidUpdate,
rpc_update: crate::veilid_client_capnp::veilid_update::Builder, mut rpc_update: crate::veilid_client_capnp::veilid_update::Builder,
) { ) {
match update { match update {
veilid_core::VeilidUpdate::Log { veilid_core::VeilidUpdate::Log {
@ -46,6 +46,9 @@ fn convert_update(
let mut att = rpc_update.init_attachment(); let mut att = rpc_update.init_attachment();
att.set_state(convert_attachment_state(state)); att.set_state(convert_attachment_state(state));
} }
veilid_core::VeilidUpdate::Shutdown => {
rpc_update.set_shutdown(());
}
} }
} }

View File

@ -275,12 +275,4 @@ impl JsVeilidCore {
}) })
} }
pub fn wait_for_state(&self, state: JsVeilidState) -> Promise {
let core = self.core.clone();
future_to_promise(async move {
let state = Self::translate_veilid_state(state)?;
core.wait_for_state(state).await;
Ok(JsValue::UNDEFINED)
})
}
} }