Hi!
In my nextjs application (pages router + trpc), I have an API call named createPlaytest as part of a simple CRUD. Right now, when it finishes creating a database entry, two things happen:
- I call sendNotifications, an async function, without awaiting it. This sends discord notifications to other users that a new playtest has been created so they can check it out. It executes in less than 3 seconds when ran manually in prod.
- I return the id of the database entry that was just created as the query response, so the front-end can redirect the user to the /playtest/{id} page.
The idea is to make the user experience better, by not having the user wait for a slow operation to finish before they get to see the result. The job is executed in the background while the user gets a response almost immediately.
const createPlaytest = protectedProcedure
.input(CreatablePlaytestSchema)
.mutation(async ({ input, ctx: { auth: { userId }} }) => {
// Check permissions
const { permissions, user } = await getPermissions(userId)
if (!user || !permissions.canCreate) throw new Error('Unauthorized')
// Create playtest
const playtests = await Collections.playtests()
const newPlaytest: Omit<Playtest, '_id'> = {
...input,
userId,
createdTimestamp: Date.now(),
closedManually: false,
applications: [],
}
const result = await playtests.insertOne(newPlaytest)
if (!result.acknowledged) throw new Error('Internal server error')
// Not awaited - this shouldn't block the user's UI.
playtestCreatedNotification({...newPlaytest, _id: result.insertedId.toString() }, user)
return result.insertedId.toString()
})
The project is open source, so if you’d like to see more detail, you can find the source code here: questcheck/src/server/routers/playtests.ts at main · Trekiros/questcheck · GitHub
What I expected to happen: the job would run in the background after the response was sent, as long as it would fit within the 10 seconds a Vercel process is allowed to stay alive
What happened instead: this works fine in dev, but in prod on Vercel, the moment the response is sent, the process is killed and the job is never completed
So, is there a way I can keep the process alive after the response has been sent? Or do I need a completely different approach? What are my options here?
Thank you
Deployment URL or Custom Domain: https://www.questcheck.org
Environment (local, preview, production): prod
Project Framework: nextjs
Build Settings:
Framework Preset: nextjs
Build Command (if not default): default
Output Directory (if not default): default
Install Command (if not default): default
Node/Runtime Version: 20.X
Package Manager: npm
Relevant Packages: trpc
(also of note, this project is at hobby level, so I can’t toggle on serverless servers, which… I believe might solve this issue?)