-
-
Notifications
You must be signed in to change notification settings - Fork 85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JSON-RPC: retrieve events via long polling #4341
Conversation
d2703c8
to
67ee039
Compare
With this PR merged we are retrieving events one-by-one, but this can further be improved by introducing a batched |
fcde9ed
to
9aeccb9
Compare
This is mostly ready except for the TypeScript part. @Simon-Laux Maybe you have some suggestions on how the TypeScript part of it should work, otherwise I will try to do the minimum to get the tests pass but it may be far from idiomatic Asynchronous JavaScript. |
@@ -165,6 +166,16 @@ impl CommandApi { | |||
get_info() | |||
} | |||
|
|||
/// Get the next event. | |||
async fn get_next_event(&self) -> Result<Event> { | |||
let event_emitter = self.accounts.read().await.get_event_emitter(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Event emitter" is just a channel receiver inside. This line basically clones a receiver so we don't hold any locks on the self.accounts
while waiting for events, otherwise it would be impossible to get a write lock to e.g. add an account because event loop is running.
1cf259f
to
457d149
Compare
Websocket example is still not fixed, but everything else is ready for review. |
main_cancel.cancelled().await; | ||
accounts.read().await.stop_io().await; | ||
drop(accounts); | ||
drop(state); | ||
let (r0, r1, r2, r3) = tokio::join!(events_task, send_task, sigterm_task, recv_task); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed join!
, it is not necessary since we already use spawn
. Just waiting for each task in a sequence.
async def wait_for_event(self, account_id: int) -> Optional[dict]: | ||
"""Waits for the next event from the given account and returns it.""" | ||
if account_id in self.event_queues: | ||
return await self.event_queues[account_id].get() | ||
return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a bug I think, now creating a queue for an account if it did not have any events before.
This way is more compatible to JSON-RPC libraries that do not support receiving notifications from the server and allows describing event types in the OpenRPC specification. Event thread converting events to notifications in the FFI is removed, so it is now possible to construct a dc_jsonrpc_instance_t while still retrieving events via dc_event_emitter_t.
7a1ea11
to
2cd82d7
Compare
07cde3c
to
4a0817d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm and works in desktop without any adjustments
it was added to JSON-RPC server in: deltachat/deltachat-core-rust#4341
This way is more compatible to JSON-RPC libraries
that do not support receiving notifications from the server and allows describing event types in the OpenRPC specification.
Event thread converting events to notifications in the FFI is removed, so it is now possible to construct a dc_jsonrpc_instance_t while still retrieving events via dc_event_emitter_t.