From 54aefcb22ee79913a214e68564d0fe8222650a7b Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Wed, 22 May 2024 05:59:13 +0200 Subject: [PATCH] Put TDLib messages in a dedicated local dataspace Communicating with TDLib on a remote dataspace is wasteful. Create and assert a local dataspace so that only messages observed by remote actors are relayed. This also allows the TDLib interface to be isolated from high-level actors. --- README.md | 22 +++++++++++++--------- config.prs | 8 +++++++- src/telegram_actor.nim | 13 +++++++------ src/telegram_actor/config.nim | 7 +++++-- telegram_actor.nimble | 2 +- 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 51f67d2..888a35b 100644 --- a/README.md +++ b/README.md @@ -26,13 +26,19 @@ let ?ds = dataspace ] $ds [ - ?? [ - $log ! + ? ?v [ + $log ! + ?- $log ! ] - ?? [ $log ! >>|: $v }> ] - ?? [ $log ! ] - ? ?v [ $log ! ] - ? [ + + # Raw TDLib interaction. + ? $messages [ + ?? [ $log ! >>|: $v }> ] + ?? [ $log ! ] + ?? [ + $log ! + ] + ! ?? [ @@ -100,9 +106,7 @@ $ds [ } } }> [ - $ds ? [ - $log ! - ] + $log ! ] ] diff --git a/config.prs b/config.prs index 7efda1d..fa6c386 100644 --- a/config.prs +++ b/config.prs @@ -1,8 +1,14 @@ version 1 . +# Assert to the actor to register a dataspace for interaction. TelegramArguments = . -# Assertion made when the client is ready to process messages. +# Assertion made to when the client is ready to process messages. TelegramReady = . + +# Asserted to telegram-client to expose TDLib messages. +# Messages received from and sent to TDLib are in the +# form of and respectively. +TDLibClient = . diff --git a/src/telegram_actor.nim b/src/telegram_actor.nim index c64179d..c50c494 100644 --- a/src/telegram_actor.nim +++ b/src/telegram_actor.nim @@ -25,21 +25,22 @@ let actor = bootActor("main") do (turn: Turn): state.initialRef = ds during(turn, ds, TelegramArguments.grabTypeFlat) do (ds: Cap): + # Extern actors assert themselves here and a ClientId # is used to isolate their conversations with tdlib. - let client = td_create_client_id() - state.subscribers[client.int] = ds + let + client = td_create_client_id() + tdlib = turn.newDataspace() + state.subscribers[client.int] = tdlib - onMessage(turn, ds, grabRecord("send", grab())) do (v: Value): + onMessage(turn, tdlib, grabRecord("send", grab())) do (v: Value): state.buffer.setPosition 0 state.buffer.writeText(v, textJson) state.buffer.data.setLen state.buffer.getPosition td_send(client, state.buffer.data) # TODO: enforce that the subscriber has not set "@client_id"? - publish(turn, ds, TelegramReady()) - # Assert to the subscriber that the messages - # it sends will be processed. + publish(turn, ds, TDLibClient(messages: tdlib.embed)) do: state.subscribers.del client.int diff --git a/src/telegram_actor/config.nim b/src/telegram_actor/config.nim index 179dcf5..4bd92c4 100644 --- a/src/telegram_actor/config.nim +++ b/src/telegram_actor/config.nim @@ -3,6 +3,9 @@ import preserves type + TDLibClient* {.preservesRecord: "tdlib".} = object + `messages`* {.preservesEmbedded.}: Value + TelegramReady* {.preservesRecord: "telegram-ready".} = object TelegramArgumentsField0* {.preservesDictionary.} = object @@ -11,8 +14,8 @@ type TelegramArguments* {.preservesRecord: "telegram-client".} = object `field0`*: TelegramArgumentsField0 -proc `$`*(x: TelegramReady | TelegramArguments): string = +proc `$`*(x: TDLibClient | TelegramReady | TelegramArguments): string = `$`(toPreserves(x)) -proc encode*(x: TelegramReady | TelegramArguments): seq[byte] = +proc encode*(x: TDLibClient | TelegramReady | TelegramArguments): seq[byte] = encode(toPreserves(x)) diff --git a/telegram_actor.nimble b/telegram_actor.nimble index 1bb78bb..0098783 100644 --- a/telegram_actor.nimble +++ b/telegram_actor.nimble @@ -1,4 +1,4 @@ -version = "20240521" +version = "20240522" author = "Emery Hemingway" description = "Telegram client as a Syndicated Actor" license = "Unlicense"