Background work
I think GPT O3 probably gave me a good response, but I want to confirm. There is no waitUntil but can either await it or use:
Downside here is inefficiency of an extra HTTP request. a
waitUntil would be useful, if possible to implement on Convex14 Replies
There's no extra http request!
Sorry, I misspoke. I meant function call, for billing.
Yea just await the scheduler
Make sure to await it
Move the functionality from the scheduled function directly into the function you’re calling from, or you can split that functionality out to a shared helper function if you need to run it in both.
But I suspect you’re scheduling a mutation from an action here. Since actions can’t directly interact with the database, a separate function call is required no matter what, unless you can turn the whole action into a mutation. Which you can’t if it’s making fetch calls for AI stuff.
So the extra call isn’t superfluous, this is things working as designed.
@erquhart interestingly, the use case is to send an analytics event to posthog within Convex Better Auth's
onCreateUser() callback.
I'll likely refactor to await ctx.scheduler.runAfter(0, ...) or just use await my HTTP request for now to keep it simple and see if it's fast enough.
But a waitUntil() primitive would be very nice to have to allow fast returns to the user, while keeping the execution context alive until the waitUntil() returns
await ctx.run* is effectively waitUntil()but with an extra function invocation
and more overhead code wise to write another internal function
It works, but waitUntil would still be handy imo
You keep saying
waitUntil, but await ctx.run* would be fine if it didn't add a function invocation to your usage - is that correct? Or is there another aspect here
Like, waitUntil could be called something else and still satisfy your goals I'm guessing, so I'm trying to understand the goals specificallyyep. the name is irrelevant to my end goal. I'm just referring to it as
waitUntil() b/c that's the name of the primitive offering this same behavior on Cloudflare (which is already used in parts of my code).That's fair. There are fundamental differences between Convex and Cloudflare workers, though.
But it sounds like you want the effect that helper functions have, without splitting out helper functions. If so, that's been requested a ton (I asked about it a lot early on myself).
Certaintly. But if both use isolates, then it seems reasonable it'd be possible to implement on Convex too
Convex functions running in connection with the database, and queries and mutations in particular being atomic transactions, are the critical difference
Actions would be simpler to do this with though I imagine, which is what would apply to your use case here
I'll summarize:
- keeps current context alive until the promise inside of
waitUntil() returns.
- no extra function call b/c it's the same context
- allows to immediately return a value to the user, while doing less essential work like analytics or logging
sure but again, that fails at one of the main goals of not being an extra function invocation. It works but is not as ideal as it could be imoHelper functions are the way to achieve what you're trying to do currently. Which, I know isn't what you're hoping for. But it's the best approach available.
I'll also say, fwiw, I stopped looking for the behavior you're describing when I really started growing my backend and began thinking of every Convex function as an api endpoint, which they are. Once you have a lot of them, it becomes an anti-pattern to have a bunch of code written directly in the endpoint, and what we call "helper functions" becomes the standard, just so you can reason about things like access.
That's been my experience, anyway.
Again, recognizing this isn't what you're asking for. But I'd encourage you to give the helper function approach a shot if you're willing. It feels like boilerplate at first, but it has a lot of advantages architecturally.