How to handle the elapse of time for debounce logic in Convex?
I’m building the notification logic for direct messaging. My app is prelaunch, and I want to keep the notification logic simple for the MVP. For now, the logic should be based on data that's simple to gather, e.g. debounce time and read receipts. In the future, we may add more factors for the logic, e.g. user presence. And more notification types, e.g. native in-app notifications.
The key challenge I’m facing in Convex is managing time-based logic to debounce email notifications. Ideally, the app delays notifications for a short period in order to group multiple messages into a single email.
Below are my current potential approaches for debouncing. Which do you recommend?
A) Convex actions to handle server-side logic for delayed email sending. My concern is whether actions are the right tool for managing time-based workflows and how they interact with Convex’s persistence model.
B) Convex scheduled functions to periodically check for new notifications and batch-send them to the client.
C) Convex Workflow component to orchestrate long-running processes, ensuring that the debounce logic executes reliably over time. I'm considering defining a workflow that delays email sending to batch multiple messages.
D) Some other approach?
17 Replies
Thanks for posting in <#1088161997662724167>.
Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets.
- Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.)
- Use search.convex.dev to search Docs, Stack, and Discord all at once.
- Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI.
- Avoid tagging staff unless specifically instructed.
Thank you!
hey, sorry to harp on this again, but @sshader attempted to tackle some of these considerations in the component. even if you all don't use the literal component, my larger point was -- I think at least some guidance on how to think about those things is embodied in that one. batching work, retrying upon service failure, etc
there is effectively some queuing and batching behavior baked into that component
so it's attempting to tackle some of these requirements you're highlighting, unless I'm misunderstanding you
I will read the component source code and see what I can learn
After reading through the source code of the component. I couldn't find code related to handling time elapsing before the notification instantiates. Perhaps the misunderstanding is that I need to figure out how to code this before the notification happens.
the sendNotification mutation just adds something to a table of notifications, it doesn't send it immediately https://github.com/get-convex/expo-push-notifications/blob/main/src/component/public.ts#L53
GitHub
expo-push-notifications/src/component/public.ts at main · get-conve...
Contribute to get-convex/expo-push-notifications development by creating an account on GitHub.
then
ensureCoordinator
is called https://github.com/get-convex/expo-push-notifications/blob/main/src/component/helpers.tsGitHub
expo-push-notifications/src/component/helpers.ts at main · get-conv...
Contribute to get-convex/expo-push-notifications development by creating an account on GitHub.
which checks on background jobs that process these notifications
you can just have those background jobs wait or something for debouncing
this is the batch processor that handles bunches of mutations: https://github.com/get-convex/expo-push-notifications/blob/main/src/component/internal.ts#L59
GitHub
expo-push-notifications/src/component/internal.ts at main · get-con...
Contribute to get-convex/expo-push-notifications development by creating an account on GitHub.
in fact, the 250ms delay here probably amounts to a bit of debouncing
GitHub
expo-push-notifications/src/component/helpers.ts at main · get-conv...
Contribute to get-convex/expo-push-notifications development by creating an account on GitHub.
So the
senders
are just a way to track the convex scheduler jobs.yeah, the coordinator is in a mutation / transactional context, and there is just one of them
their job is to make sure things get sent
they schedule N
senders
which actually run the action to talk to the service
the coordinator will obey batching rules and the like
and own retries on failureOkay that make sense
And the senderCoordinator controls a batch of senders?
it schedules off a number of concurrent senders who are all talking to the service
starting here
GitHub
expo-push-notifications/src/component/internal.ts at main · get-con...
Contribute to get-convex/expo-push-notifications development by creating an account on GitHub.
Okay so the senderCoordinator is a central orchestrator for notifications and the senders are like workers which get assigned task by this coordinator.
yep
And the senders are created and destroyed depending on the notification load. And the senders can be paused if needed to create a debouncing effect.
Thank you Jamie, this code helped me see a starting point for the system I want to implement with convex.