Dev vs Production deployment

According to the documentation, when creating a project with the Vue framework, it also creates an additional worker under server/index.js. I have written a worker that interacts with the D1 service in this file. When in development (npm run dev) the worker interacts with d1 without any problems. When deploying it to production (npm run deploy), the query function works as expected, but update function does not appear to be working. I have tried watching the logs and it appears to be exectuing the function as expected, but the database never reflects any of the updates Here is the fetch function that retrieves the data that works as expected: if (pathname === "/api/products") { const { results } = await env.DB.prepare( "SELECT * FROM NxStage" ) .bind() .all(); return Response.json(results); } Here is the fetch function that writes updates. Works in dev but not in production: if (pathname === "/api/updates") { // console.log(params); params.forEach(async (value, key) => { // console.log(key, value); console.log(UPDATE NxStage SET Qty = ${value} WHERE ID = ${key}) const { results } = await env.DB.prepare( "UPDATE NxStage SET Qty = ? WHERE ID = ?" ).bind(value, key).run() }); return new Response(null, { status: 200 }); } Any help is greatly appreciated. I am sure I am missing something small. This one has me perplexed.
4 Replies
Viktor
Viktor4w ago
You are running an async function in forEach without waiting for it a stack level above. In live this won't wait for your queries to finish but kill them after request. You should consider doing
if (pathname === "/api/updates") {
// console.log(params);
for (const [key, value] of params.entries()) {
console.log(`UPDATE NxStage SET Qty = ${value} WHERE ID = ${key}`);
await env.DB.prepare(
"UPDATE NxStage SET Qty = ? WHERE ID = ?"
).bind(value, key).run();
}
return new Response(null, { status: 200 });
}
if (pathname === "/api/updates") {
// console.log(params);
for (const [key, value] of params.entries()) {
console.log(`UPDATE NxStage SET Qty = ${value} WHERE ID = ${key}`);
await env.DB.prepare(
"UPDATE NxStage SET Qty = ? WHERE ID = ?"
).bind(value, key).run();
}
return new Response(null, { status: 200 });
}
or, to make the promise queue parallel, ```js if (pathname === "/api/updates") { // console.log(params); const queue = []; for (const [key, value] of params.entries()) { console.log(UPDATE NxStage SET Qty = ${value} WHERE ID = ${key}); queue.push(env.DB.prepare( "UPDATE NxStage SET Qty = ? WHERE ID = ?" ).bind(value, key).run()); } await Promise.all(queue); return new Response(null, { status: 200 }); } ``` A different approach would be to queue your promises in a way that they'll be executed even after you returned your promises (and the worker would have been normally killed) ```js if (pathname === "/api/updates") { // console.log(params); params.forEach(async (value, key) => { console.log(UPDATE NxStage SET Qty = ${ value } WHERE ID = ${ key }`) // This will evecute the promise even after you return the response event.waitUntil(env.DB.prepare( "UPDATE NxStage SET Qty = ? WHERE ID = ?" ).bind(value, key).run()); }); return new Response(null, { status: 200 }); } ```
mast3rof0
mast3rof0OP4w ago
@Viktor First, thank you for this. Unfortunately, I have not touched node/js in almost 10 years so a lot has changed. Still little perplexed as the this line seems to be where the problems lie but I can't say I truly understand why. params.forEach(async (value, key) => vs for (const [key, value] of params.entries()) I thought the await env.DB statement would wait for the response before moving on to the next iteration of the loop. If it is too in-depth of a discussion, I fully understand. Defnitely need to do some more work on this. But I did want to say thank you
Viktor
Viktor4w ago
I am not sure about how to explain this properly. With forEach you call new functions. You are awaiting the queries in it, but you are not awaiting the outer function. Thats like I write an instruction - for every driver —- drive to the next supermarket —- wait till you are there —- buy some strawberries - then eat all strawberries Steps in js will be 1. for all drivers 2. eat all strawberries - (Process done, Cloudflare kills process) 3. first driver arrives at supermarket With forEach you are opening a new stack which you did not await. That‘s why I am not using forEach. My third options tells cloudflare that we know about some Promises that we did not yet await, but we ask cloudflare to not kill our process but event.waitUntil they were done, too
mast3rof0
mast3rof0OP4w ago
I think I understand. Ultimately, it comes down to understanding the forEach method and how it is processed compared to the entries method. Appreciate it!

Did you find this page helpful?