From 10b0c9c80edf81592c4d3fa5601b0a42209ef8d1 Mon Sep 17 00:00:00 2001 From: Brandon Vandegrift <798832-bmv437@users.noreply.gitlab.com> Date: Wed, 9 Apr 2025 00:51:57 -0400 Subject: [PATCH] Expose the is_shutdown API to all bindings --- veilid-core/src/veilid_api/json_api/mod.rs | 4 ++ veilid-flutter/lib/veilid.dart | 1 + veilid-flutter/lib/veilid_ffi.dart | 13 +++++++ veilid-flutter/lib/veilid_js.dart | 5 +++ veilid-flutter/rust/src/dart_ffi.rs | 17 +++++++++ veilid-python/veilid/api.py | 4 ++ veilid-python/veilid/json_api.py | 3 ++ veilid-python/veilid/operations.py | 1 + veilid-python/veilid/schema/RecvMessage.json | 40 +++++++++++++++++++- veilid-python/veilid/schema/Request.json | 16 +++++++- veilid-wasm/src/lib.rs | 13 +++++++ veilid-wasm/src/veilid_client_js.rs | 11 ++++++ 12 files changed, 126 insertions(+), 2 deletions(-) diff --git a/veilid-core/src/veilid_api/json_api/mod.rs b/veilid-core/src/veilid_api/json_api/mod.rs index 7b7a2d38..b807bdac 100644 --- a/veilid-core/src/veilid_api/json_api/mod.rs +++ b/veilid-core/src/veilid_api/json_api/mod.rs @@ -143,6 +143,10 @@ pub enum ResponseOp { #[serde(flatten)] result: ApiResult>, }, + IsShutdown { + #[serde(flatten)] + result: ApiResult, + }, Attach { #[serde(flatten)] result: ApiResult<()>, diff --git a/veilid-flutter/lib/veilid.dart b/veilid-flutter/lib/veilid.dart index bd0555d0..5df6e970 100644 --- a/veilid-flutter/lib/veilid.dart +++ b/veilid-flutter/lib/veilid.dart @@ -137,6 +137,7 @@ abstract class Veilid { void changeLogIgnore(String layer, List changes); Future> startupVeilidCore(VeilidConfig config); Future getVeilidState(); + Future isShutdown(); Future attach(); Future detach(); Future shutdownVeilidCore(); diff --git a/veilid-flutter/lib/veilid_ffi.dart b/veilid-flutter/lib/veilid_ffi.dart index 72c89247..98b2ec0f 100644 --- a/veilid-flutter/lib/veilid_ffi.dart +++ b/veilid-flutter/lib/veilid_ffi.dart @@ -38,6 +38,8 @@ typedef _ChangeLogIgnoreDart = void Function(Pointer, Pointer); typedef _StartupVeilidCoreDart = void Function(int, int, Pointer); // fn get_veilid_state(port: i64) typedef _GetVeilidStateDart = void Function(int); +// fn is_shutdown(port: i64) +typedef _IsShutdownDart = void Function(int); // fn attach(port: i64) typedef _AttachDart = void Function(int); // fn detach(port: i64) @@ -1251,6 +1253,8 @@ class VeilidFFI extends Veilid { _startupVeilidCore = dylib.lookupFunction< Void Function(Int64, Int64, Pointer), _StartupVeilidCoreDart>('startup_veilid_core'), + _isShutdown = dylib.lookupFunction( + 'is_shutdown'), _getVeilidState = dylib.lookupFunction( 'get_veilid_state'), @@ -1490,6 +1494,7 @@ class VeilidFFI extends Veilid { final _ChangeLogIgnoreDart _changeLogIgnore; final _StartupVeilidCoreDart _startupVeilidCore; final _GetVeilidStateDart _getVeilidState; + final _IsShutdownDart _isShutdown; final _AttachDart _attach; final _DetachDart _detach; final _ShutdownVeilidCoreDart _shutdownVeilidCore; @@ -1623,6 +1628,14 @@ class VeilidFFI extends Veilid { return processFutureJson(VeilidState.fromJson, recvPort.first); } + @override + Future isShutdown() async { + final recvPort = ReceivePort('is_shutdown'); + final sendPort = recvPort.sendPort; + _isShutdown(sendPort.nativePort); + return processFuturePlain(recvPort.first); + } + @override Future attach() async { final recvPort = ReceivePort('attach'); diff --git a/veilid-flutter/lib/veilid_js.dart b/veilid-flutter/lib/veilid_js.dart index a56fc797..5a4b39b0 100644 --- a/veilid-flutter/lib/veilid_js.dart +++ b/veilid-flutter/lib/veilid_js.dart @@ -627,6 +627,11 @@ class VeilidJS extends Veilid { VeilidState.fromJson(jsonDecode(await _wrapApiPromise( js_util.callMethod(wasm, 'get_veilid_state', [])))); + @override + Future isShutdown() async => + await _wrapApiPromise( + js_util.callMethod(wasm, 'is_shutdown', [])); + @override Future attach() => _wrapApiPromise(js_util.callMethod(wasm, 'attach', [])); diff --git a/veilid-flutter/rust/src/dart_ffi.rs b/veilid-flutter/rust/src/dart_ffi.rs index 5eb3fdca..e7dacc06 100644 --- a/veilid-flutter/rust/src/dart_ffi.rs +++ b/veilid-flutter/rust/src/dart_ffi.rs @@ -482,6 +482,23 @@ pub extern "C" fn get_veilid_state(port: i64) { ); } +#[no_mangle] +#[instrument(level = "trace", target = "ffi", skip_all)] +pub extern "C" fn is_shutdown(port: i64) { + DartIsolateWrapper::new(port).spawn_result( + async move { + let veilid_api = get_veilid_api().await; + if let Err(veilid_core::VeilidAPIError::NotInitialized) = veilid_api { + return APIResult::Ok(true); + } + let veilid_api = veilid_api.unwrap(); + let is_shutdown = veilid_api.is_shutdown(); + APIResult::Ok(is_shutdown) + } + .in_current_span(), + ); +} + #[no_mangle] #[instrument(level = "trace", target = "ffi", skip_all)] pub extern "C" fn attach(port: i64) { diff --git a/veilid-python/veilid/api.py b/veilid-python/veilid/api.py index b54786de..6a6f540c 100644 --- a/veilid-python/veilid/api.py +++ b/veilid-python/veilid/api.py @@ -374,6 +374,10 @@ class VeilidAPI(ABC): async def get_state(self) -> VeilidState: pass + @abstractmethod + async def is_shutdown(self) -> bool: + pass + @abstractmethod async def attach(self): pass diff --git a/veilid-python/veilid/json_api.py b/veilid-python/veilid/json_api.py index 0a88051c..9682f724 100644 --- a/veilid-python/veilid/json_api.py +++ b/veilid-python/veilid/json_api.py @@ -323,6 +323,9 @@ class _JsonVeilidAPI(VeilidAPI): return VeilidState.from_json( raise_api_result(await self.send_ndjson_request(Operation.GET_STATE)) ) + + async def is_shutdown(self) -> bool: + return raise_api_result(await self.send_ndjson_request(Operation.IS_SHUTDOWN)) async def attach(self): raise_api_result(await self.send_ndjson_request(Operation.ATTACH)) diff --git a/veilid-python/veilid/operations.py b/veilid-python/veilid/operations.py index 24d26121..7b61f2b2 100644 --- a/veilid-python/veilid/operations.py +++ b/veilid-python/veilid/operations.py @@ -5,6 +5,7 @@ from typing import Self class Operation(StrEnum): CONTROL = "Control" GET_STATE = "GetState" + IS_SHUTDOWN = "IsShutdown" ATTACH = "Attach" DETACH = "Detach" NEW_PRIVATE_ROUTE = "NewPrivateRoute" diff --git a/veilid-python/veilid/schema/RecvMessage.json b/veilid-python/veilid/schema/RecvMessage.json index 47da68d6..157bdf4a 100644 --- a/veilid-python/veilid/schema/RecvMessage.json +++ b/veilid-python/veilid/schema/RecvMessage.json @@ -81,6 +81,44 @@ } } }, + { + "type": "object", + "anyOf": [ + { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "boolean" + } + } + }, + { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "$ref": "#/definitions/VeilidAPIError" + } + } + } + ], + "required": [ + "op" + ], + "properties": { + "op": { + "type": "string", + "enum": [ + "IsShutdown" + ] + } + } + }, { "type": "object", "anyOf": [ @@ -4772,4 +4810,4 @@ } } } -} +} \ No newline at end of file diff --git a/veilid-python/veilid/schema/Request.json b/veilid-python/veilid/schema/Request.json index 49fb62b5..591f1d2b 100644 --- a/veilid-python/veilid/schema/Request.json +++ b/veilid-python/veilid/schema/Request.json @@ -38,6 +38,20 @@ } } }, + { + "type": "object", + "required": [ + "op" + ], + "properties": { + "op": { + "type": "string", + "enum": [ + "IsShutdown" + ] + } + } + }, { "type": "object", "required": [ @@ -1818,4 +1832,4 @@ ] } } -} +} \ No newline at end of file diff --git a/veilid-wasm/src/lib.rs b/veilid-wasm/src/lib.rs index 67ada469..1c9344ff 100644 --- a/veilid-wasm/src/lib.rs +++ b/veilid-wasm/src/lib.rs @@ -326,6 +326,19 @@ pub fn get_veilid_state() -> Promise { }) } +#[wasm_bindgen()] +pub fn is_shutdown() -> Promise { + wrap_api_future_json(async move { + let veilid_api = get_veilid_api(); + if let Err(veilid_core::VeilidAPIError::NotInitialized) = veilid_api { + return APIResult::Ok(true); + } + let veilid_api = veilid_api.unwrap(); + let is_shutdown = veilid_api.is_shutdown().await?; + APIResult::Ok(is_shutdown) + }) +} + #[wasm_bindgen()] pub fn attach() -> Promise { wrap_api_future_void(async move { diff --git a/veilid-wasm/src/veilid_client_js.rs b/veilid-wasm/src/veilid_client_js.rs index e2c70d47..0b153b87 100644 --- a/veilid-wasm/src/veilid_client_js.rs +++ b/veilid-wasm/src/veilid_client_js.rs @@ -160,6 +160,17 @@ impl VeilidClient { APIRESULT_UNDEFINED } + /// Check if Veilid is shutdown. + pub async fn isShutdown() -> APIResult { + let veilid_api = get_veilid_api(); + if let Err(veilid_core::VeilidAPIError::NotInitialized) = veilid_api { + return APIResult::Ok(true); + } + let veilid_api = veilid_api.unwrap(); + let is_shutdown = veilid_api.is_shutdown(); + APIResult::Ok(is_shutdown) + } + /// Get a full copy of the current state of Veilid. pub async fn getState() -> APIResult { let veilid_api = get_veilid_api()?;