CodingWithJamal
CodingWithJamal2mo ago

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
Convex Bot
Convex Bot2mo ago
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!
jamwt
jamwt2mo ago
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
CodingWithJamal
CodingWithJamalOP2mo ago
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.
jamwt
jamwt2mo ago
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.
jamwt
jamwt2mo ago
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.
jamwt
jamwt2mo ago
which checks on background jobs that process these notifications you can just have those background jobs wait or something for debouncing
jamwt
jamwt2mo ago
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.
jamwt
jamwt2mo ago
in fact, the 250ms delay here probably amounts to a bit of debouncing
CodingWithJamal
CodingWithJamalOP2mo ago
So the senders are just a way to track the convex scheduler jobs.
jamwt
jamwt2mo ago
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 failure
CodingWithJamal
CodingWithJamalOP2mo ago
Okay that make sense
senders: defineTable({
jobId: v.id("_scheduled_functions"),
checkJobId: v.id("_scheduled_functions"),
}),
senderCoordinator: defineTable({
jobId: v.id("_scheduled_functions"),
}),
senders: defineTable({
jobId: v.id("_scheduled_functions"),
checkJobId: v.id("_scheduled_functions"),
}),
senderCoordinator: defineTable({
jobId: v.id("_scheduled_functions"),
}),
And the senderCoordinator controls a batch of senders?
jamwt
jamwt2mo ago
it schedules off a number of concurrent senders who are all talking to the service starting here
CodingWithJamal
CodingWithJamalOP2mo ago
Okay so the senderCoordinator is a central orchestrator for notifications and the senders are like workers which get assigned task by this coordinator.
jamwt
jamwt2mo ago
yep
CodingWithJamal
CodingWithJamalOP2mo ago
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.

Did you find this page helpful?