feat(channels): add channelExists to reliable channels API (#4045)

This commit is contained in:
Ivan FB 2026-07-16 18:38:05 +02:00 committed by GitHub
parent 0a19473a3b
commit 1c83c32397
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 69 additions and 0 deletions

View File

@ -30,6 +30,21 @@ proc logosdelivery_channel_create(
return ok(string(id))
proc logosdelivery_channel_exists(
ctx: ptr FFIContext[LogosDelivery],
callback: FFICallBack,
userData: pointer,
channelIdStr: cstring,
) {.ffi.} =
## Returns `"true"` or `"false"`; a missing channel is not an error.
requireInitializedNode(ctx, "ChannelExists"):
return err(errMsg)
requireChannels(ctx, "ChannelExists"):
return err(errMsg)
return ok($ctx.myLib[].reliableChannelManager.channelExists(ChannelId($channelIdStr)))
proc logosdelivery_channel_send(
ctx: ptr FFIContext[LogosDelivery],
callback: FFICallBack,

View File

@ -86,6 +86,13 @@ extern "C"
const char *contentTopic,
const char *senderId);
// Check whether a reliable channel is currently open. Returns "true" or
// "false"; an unknown channel id is not an error.
int logosdelivery_channel_exists(void *ctx,
FFICallBack callback,
void *userData,
const char *channelId);
// Send a message on a reliable channel.
// messageJson: { "payload": "base64-encoded-payload", "ephemeral": false }
// Returns a request ID that can be used to track delivery.

View File

@ -10,6 +10,7 @@ type ReliableChannelApi* = concept c
createReliableChannel(
c, channelId = ChannelId, contentTopic = ContentTopic, senderId = SdsParticipantID
) is Result[ChannelId, string]
channelExists(c, channelId = ChannelId) is bool
closeChannel(c, channelId = ChannelId) is Future[Result[void, string]]
send(c, channelId = ChannelId, appPayload = seq[byte]) is
Future[Result[RequestId, string]]

View File

@ -74,6 +74,12 @@ proc createReliableChannel*(
self.channels[channelId] = chn
return ok(channelId)
proc channelExists*(self: ReliableChannelManager, channelId: ChannelId): bool =
## True while the channel is held by the manager, i.e. between a successful
## `createReliableChannel` and `closeChannel`. Persisted SDS state for a
## closed channel does not count as existing.
return self.channels.hasKey(channelId)
proc closeChannel*(
self: ReliableChannelManager, channelId: ChannelId
): Future[Result[void, string]] {.async: (raises: []).} =

View File

@ -1,3 +1,4 @@
{.used.}
import ./test_channel_lifecycle
import ./test_reliable_channel_send_receive

View File

@ -0,0 +1,39 @@
{.used.}
import chronos, testutils/unittests
import brokers/broker_context
import ../testlib/[common, testasync]
import logos_delivery/api/conf/channels_conf
import logos_delivery/channels/reliable_channel_manager
import logos_delivery/channels/api/channel_lifecycle
import logos_delivery/channels/encryption/noop_encryption
suite "Reliable Channel - lifecycle":
asyncTest "channelExists tracks create and close":
const
channelId = ChannelId("lifecycle-channel")
contentTopic = ContentTopic("/reliable-channel/test/proto")
var manager: ReliableChannelManager
lockNewGlobalBrokerContext:
manager = ReliableChannelManager.new(ReliableChannelManagerConf()).expect(
"ReliableChannelManager.new"
)
setNoopEncryption()
check not manager.channelExists(channelId)
discard manager
.createReliableChannel(channelId, contentTopic, SdsParticipantID("local"))
.expect("createReliableChannel")
check manager.channelExists(channelId)
## An unrelated id must not be reported as existing.
check not manager.channelExists(ChannelId("other-channel"))
(await manager.closeChannel(channelId)).expect("closeChannel")
check not manager.channelExists(channelId)