Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion library/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ void *logosdelivery_create_node(
**Returns:** the context handle, or `NULL` on failure. Creation is asynchronous:
wait for `onCreated` before you make any other call.

A context whose `onCreated` reported `RET_ERR` stays live but holds no node.
Every later call on it answers `RET_ERR` with `library is not initialized: the
constructor failed or has not run yet`, and `logosdelivery_destroy` still
releases it.

**Example configuration JSON:**
```json
{
Expand Down Expand Up @@ -108,7 +113,8 @@ int logosdelivery_start_node(void *ctx, LogosDeliveryScalarRawFn callback, void
```

#### `logosdelivery_stop_node`
Stops the node.
Stops the node and removes the event listeners. A second call is a no-op that
reports `RET_OK`.

```c
int logosdelivery_stop_node(void *ctx, LogosDeliveryScalarRawFn callback, void *userData);
Expand All @@ -122,6 +128,30 @@ use `ctx` afterwards.
int logosdelivery_destroy(void *ctx);
```

Stops the node first if it still runs, so skipping `logosdelivery_stop_node` no
longer leaves a live node behind. It blocks for up to 15 s at the nim-ffi
defaults (`2 * ffiRecycleTimeoutMs + ffiTeardownTimeoutMs + 2 s`).

Prefer an explicit `logosdelivery_stop_node`: a failed stop here is only logged
(`RET_ERR` covers an invalid `ctx` and a failed context teardown, nothing else),
and nim-ffi cancels the stop at `ffiTeardownTimeoutMs` (10 s), leaving the node
half stopped.

### Context-free calls

No `ctx` and no callback: `dlsym` the symbol and read the return value.

#### `logosdelivery_version`
Version and git commit hash. Callable before `logosdelivery_create_node`, though
the first call into the library starts the Nim runtime.

```c
const char *logosdelivery_version(void);
```

The buffer belongs to the calling thread and stays valid until that thread calls
`logosdelivery_version` again, so copy the bytes.

### Messaging

#### `logosdelivery_subscribe`
Expand Down
8 changes: 6 additions & 2 deletions library/liblogosdelivery.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
// The call surface is generated from the {.ffi.} annotations in library/*.nim
// and written to generated/logosdelivery.h by `make liblogosdelivery`. That file
// is a build artifact, not checked in, so build the library before you compile
// against this header. This file adds the event-listener ABI, which nim-ffi
// exports from declareLibrary but does not emit into the `abi = c` header.
// against this header. This file adds what nim-ffi exports but leaves out of the
// `abi = c` header: the event-listener ABI, and the `{.ffiExport.}` procs.
#pragma once
#ifndef __liblogosdelivery__
#define __liblogosdelivery__
Expand Down Expand Up @@ -32,6 +32,10 @@ extern "C"
{
#endif

// Version and git commit hash. Needs no ctx. The buffer belongs to the calling
// thread and lasts until that thread calls this again, so copy it.
const char *logosdelivery_version(void);

// Raw result-delivery callback used by the event API. `msg` is a byte run of
// `len` bytes, not NUL-terminated, and is valid only for the duration of the
// call.
Expand Down
1 change: 1 addition & 0 deletions library/liblogosdelivery.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ include
./logos_delivery_api/node_api,
./logos_delivery_api/messaging_api,
./logos_delivery_api/debug_api,
./logos_delivery_api/sync_exports,
./kernel_api/peer_manager_api,
./kernel_api/discovery_api,
./kernel_api/debug_node_api,
Expand Down
24 changes: 16 additions & 8 deletions library/logos_delivery_api/node_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -179,13 +179,6 @@ proc logosdelivery_create_node(

return ok(lib)

proc logosdelivery_destroy(self: LogosDelivery) {.ffiDtor.} =
## nim-ffi runs this when the host destroys the node, before the FFI
## thread can serve a later create. The forwarders registered at create
## feed the C listener registry, which lives from create to destroy; the
## node's broker scope carries them and dies with the node, here.
await self.teardownFFIEventScope()

proc logosdelivery_start_node(
self: LogosDelivery
): Future[Result[string, string]] {.ffi.} =
Expand All @@ -195,11 +188,26 @@ proc logosdelivery_start_node(
return err("failed to start: " & errMsg)
return ok("")

proc stopNode(self: LogosDelivery): Future[Result[void, string]] {.async.} =
if not self.isRunning():
return ok()

await self.stop()

proc logosdelivery_stop_node(
self: LogosDelivery
): Future[Result[string, string]] {.ffi.} =
(await self.stop()).isOkOr:
(await self.stopNode()).isOkOr:
let errMsg = $error
chronicles.error "STOP_NODE failed", err = errMsg
return err("failed to stop: " & errMsg)
return ok("")

proc logosdelivery_destroy(self: LogosDelivery) {.ffiDtor.} =
## Safety net for a host that skips `stop_node` (#4108): nim-ffi recycles the
## worker rather than joining it, so an unstopped node keeps running.
## The forwarders registered at create live until here, with the node's
## broker scope; `teardownFFIEventScope` is the other end of create.
(await self.stopNode()).isOkOr:
chronicles.error "DESTROY failed", err = error
await self.teardownFFIEventScope()
6 changes: 6 additions & 0 deletions library/logos_delivery_api/sync_exports.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## `{.ffiExport.}` entry points: no context, no callback, the value crosses the
## C ABI directly.

proc logosdelivery_version(): string {.ffiExport.} =
## Same string `waku_version` answers over the context surface.
WakuNodeVersionString
6 changes: 3 additions & 3 deletions logos_delivery.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ requires "nim >= 2.2.4",
"zlib",
# Debug & Testing
"testutils",
"unittest2"
"unittest2",
# FFI
"ffi == 0.3.0"

# Packages not on nimble (use git URLs)

requires "https://github.com/logos-messaging/nim-ffi#53515de17af0ef3e88b2aec9675b8163dddc14ae" # v0.3.0-rc.2

requires "https://github.com/logos-messaging/nim-sds.git#b12f5ee07c5b764303b51fb948b32a4ade1de3b5"

requires "https://github.com/NagyZoltanPeter/nim-brokers.git#v3.3.0"
Expand Down
8 changes: 8 additions & 0 deletions logos_delivery/logos_delivery.nim
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,14 @@ proc stop*(self: LogosDelivery): Future[Result[void, string]] {.async.} =

return ok()

func isRunning*(self: LogosDelivery): bool =
## True while a layer still holds what `stop` releases; the channel manager
## needs no test, its `stop` is already a no-op when empty.
let transportUp =
not self.waku.isNil() and not self.waku.node.isNil() and self.waku.node.started
let messagingUp = not self.messagingClient.isNil() and self.messagingClient.started
transportUp or messagingUp

proc isOnline*(self: LogosDelivery): Future[Result[bool, string]] {.async.} =
if self.waku.isNil():
return err("Waku node is not initialized")
Expand Down
4 changes: 2 additions & 2 deletions nimble.lock
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@
},
"ffi": {
"version": "0.3.0",
"vcsRevision": "53515de17af0ef3e88b2aec9675b8163dddc14ae",
"vcsRevision": "b6c17dc822960b626d76d814de90208c0a40a44e",
"url": "https://github.com/logos-messaging/nim-ffi",
"downloadMethod": "git",
"dependencies": [
Expand All @@ -655,7 +655,7 @@
"cbor_serialization"
],
"checksums": {
"sha1": "1d84ceaf8594f4970c5a37f916003ffc0531dc4e"
"sha1": "74e796df3ef39d828e014df701127edfbee459e0"
}
},
"boringssl": {
Expand Down
4 changes: 2 additions & 2 deletions nix/deps.nix
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,8 @@

ffi = pkgs.fetchgit {
url = "https://github.com/logos-messaging/nim-ffi";
rev = "53515de17af0ef3e88b2aec9675b8163dddc14ae";
sha256 = "0ncf9j7fhgd3nswr4rh19jx77dl974sajphdl04cb602hshgj5ij";
rev = "b6c17dc822960b626d76d814de90208c0a40a44e";
sha256 = "1sjnax54j39igsxkig095grj4x3j9div4fimrmz609byhp4qdavh";
fetchSubmodules = true;
};

Expand Down
2 changes: 1 addition & 1 deletion nix/submodules.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
{
"path": "vendor/nim-ffi",
"url": "https://github.com/logos-messaging/nim-ffi",
"rev": "53515de17af0ef3e88b2aec9675b8163dddc14ae"
"rev": "b6c17dc822960b626d76d814de90208c0a40a44e"
}
,
{
Expand Down
Loading
Loading