Skip to content

Commit 1c83c32

Browse files
feat(channels): add channelExists to reliable channels API (#4045)
1 parent 0a19473 commit 1c83c32

6 files changed

Lines changed: 69 additions & 0 deletions

File tree

library/channels_api/channel_api.nim

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,21 @@ proc logosdelivery_channel_create(
3030

3131
return ok(string(id))
3232

33+
proc logosdelivery_channel_exists(
34+
ctx: ptr FFIContext[LogosDelivery],
35+
callback: FFICallBack,
36+
userData: pointer,
37+
channelIdStr: cstring,
38+
) {.ffi.} =
39+
## Returns `"true"` or `"false"`; a missing channel is not an error.
40+
requireInitializedNode(ctx, "ChannelExists"):
41+
return err(errMsg)
42+
43+
requireChannels(ctx, "ChannelExists"):
44+
return err(errMsg)
45+
46+
return ok($ctx.myLib[].reliableChannelManager.channelExists(ChannelId($channelIdStr)))
47+
3348
proc logosdelivery_channel_send(
3449
ctx: ptr FFIContext[LogosDelivery],
3550
callback: FFICallBack,

library/liblogosdelivery.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ extern "C"
8686
const char *contentTopic,
8787
const char *senderId);
8888

89+
// Check whether a reliable channel is currently open. Returns "true" or
90+
// "false"; an unknown channel id is not an error.
91+
int logosdelivery_channel_exists(void *ctx,
92+
FFICallBack callback,
93+
void *userData,
94+
const char *channelId);
95+
8996
// Send a message on a reliable channel.
9097
// messageJson: { "payload": "base64-encoded-payload", "ephemeral": false }
9198
// Returns a request ID that can be used to track delivery.

logos_delivery/api/reliable_channel_manager_api.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ type ReliableChannelApi* = concept c
1010
createReliableChannel(
1111
c, channelId = ChannelId, contentTopic = ContentTopic, senderId = SdsParticipantID
1212
) is Result[ChannelId, string]
13+
channelExists(c, channelId = ChannelId) is bool
1314
closeChannel(c, channelId = ChannelId) is Future[Result[void, string]]
1415
send(c, channelId = ChannelId, appPayload = seq[byte]) is
1516
Future[Result[RequestId, string]]

logos_delivery/channels/api/channel_lifecycle.nim

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ proc createReliableChannel*(
7474
self.channels[channelId] = chn
7575
return ok(channelId)
7676

77+
proc channelExists*(self: ReliableChannelManager, channelId: ChannelId): bool =
78+
## True while the channel is held by the manager, i.e. between a successful
79+
## `createReliableChannel` and `closeChannel`. Persisted SDS state for a
80+
## closed channel does not count as existing.
81+
return self.channels.hasKey(channelId)
82+
7783
proc closeChannel*(
7884
self: ReliableChannelManager, channelId: ChannelId
7985
): Future[Result[void, string]] {.async: (raises: []).} =

tests/channels/test_all.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{.used.}
22

3+
import ./test_channel_lifecycle
34
import ./test_reliable_channel_send_receive
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{.used.}
2+
3+
import chronos, testutils/unittests
4+
import brokers/broker_context
5+
6+
import ../testlib/[common, testasync]
7+
8+
import logos_delivery/api/conf/channels_conf
9+
import logos_delivery/channels/reliable_channel_manager
10+
import logos_delivery/channels/api/channel_lifecycle
11+
import logos_delivery/channels/encryption/noop_encryption
12+
13+
suite "Reliable Channel - lifecycle":
14+
asyncTest "channelExists tracks create and close":
15+
const
16+
channelId = ChannelId("lifecycle-channel")
17+
contentTopic = ContentTopic("/reliable-channel/test/proto")
18+
19+
var manager: ReliableChannelManager
20+
lockNewGlobalBrokerContext:
21+
manager = ReliableChannelManager.new(ReliableChannelManagerConf()).expect(
22+
"ReliableChannelManager.new"
23+
)
24+
setNoopEncryption()
25+
26+
check not manager.channelExists(channelId)
27+
28+
discard manager
29+
.createReliableChannel(channelId, contentTopic, SdsParticipantID("local"))
30+
.expect("createReliableChannel")
31+
32+
check manager.channelExists(channelId)
33+
34+
## An unrelated id must not be reported as existing.
35+
check not manager.channelExists(ChannelId("other-channel"))
36+
37+
(await manager.closeChannel(channelId)).expect("closeChannel")
38+
39+
check not manager.channelExists(channelId)

0 commit comments

Comments
 (0)