Discuss and resolve questions on Liquid, JavaScript, themes, sales channels, and site speed enhancements.
My API route which polls 3rd party APIs is failing after exactly 30seconds even though I am calling waitUntil repeatedly.
It seems the waitUntil property from the underlying worker API is not working properly.
Very frustrating because everything works locally, but the deployed environment doesn't work.
Please help and provide advice where you can.
Here is the essence of my code:
export async function action({request, params, context}: ActionFunctionArgs) {
const body = (await request.json()) as TrainingCompleteResponse;
// Moving this below the action led to some webhook handling bugs for me. Maybe moving it above so it's defined before it's used would work too? Leaving it here for now.
const handleEvent = async (
body: TrainingCompleteResponse,
context: AppLoadContext,
) => {
// lots of fetches
};
// Kick off event handler asynchronously and use waitUntil() repeatedly until
// handler finishes to prevent worker from killing the handleEvent()
// function early
const handleEventPromise = handleEvent(body, context)
.then(() => {
console.log('Trained model event handler finished successfully');
})
.catch((error) => {
console.error('Error handling trained model event: ', error.message);
});
const refreshWorkerUntilPromiseFinishes = async (
promiseToWaitFor: Promise<any>,
) => {
const pending = {
state: 'pending',
};
function getPromiseState(promise: Promise<any>) {
// We put `pending` promise after the promise to test,
// which forces .race to test `promise` first
return Promise.race([promise, pending]).then(
(value) => {
if (value === pending) {
return value;
}
return {
state: 'resolved',
value,
};
},
(reason) => ({state: 'rejected', reason}),
);
}
let promiseState = await getPromiseState(promiseToWaitFor);
while (promiseState === pending) {
// If promise we want to wait to finish isn't finished, call waitUntil again and wait 15 secs
console.log('calling waitUntil to keep event handling worker alive');
context.waitUntil(handleEventPromise);
await new Promise((r) => setTimeout(r, 15_000));
promiseState = await getPromiseState(promiseToWaitFor);
}
console.log('event handling done');
};
context.waitUntil(refreshWorkerUntilPromiseFinishes(handleEventPromise));
return json(null, 202);
}
As you can see I am calling waitUntil with a promise until the underlying promise is resolved, which should continually extend the life of my worker. However, looking at the logs for this request indicate it lives for exactly 30secs then dies.
Request id:
o2-c993991c-bd5e-43e0-adad-154e3471c468.86685b880b1a43fb
Logs (notice first log seconds time is 19, last is 49, indicating exactly 30secs elapsed):
By investing 30 minutes of your time, you can unlock the potential for increased sales,...
By Jacqui Sep 11, 2024We appreciate the diverse ways you participate in and engage with the Shopify Communi...
By JasonH Sep 9, 2024Thanks to everyone who participated in our AMA with 2H Media: Marketing Your Shopify St...
By Jacqui Sep 6, 2024