I have following problem: I let two functions write into my database. Before they get inserted into the database I check if a similar item exists:
const storeListing = async listing => {
//Some logic
const foundSimilar = await findSimilar(listing);
if(!foundSimilar){
await insertListing(listing)
}else{
//Perform duplicate check
if(foundSimilar.buildingType===listing.buildingType){
console.log('found')
}
}
}
Now when I do following:
const test = () => {
storeListing({buildingType:'MFH'});
storeListing({buildingType:'MFH'});
}
The else condition with the duplicate check is never triggered.
My idea would be that the two functions get handled sequentially (event loop). So storeListing can not be called again before one is done.
So do I have a logical issue here or is it just the database having eventual consistency?
Edit: When I do not know how many other functions call storeListing and I want it to happen serialized (e.g. I have storeListing for Multi family house - store listing for single family house).
Is this a good pattern:
const lock={};
export const storeListing = async (listing, type) => {
const id= uuidv1();
while (Object.keys(lock).length>0){
await timeout(15);
}
threadLock[id]=true;
//Function like above
delete lock[id];
}
Even if the insertion order isn't relevant you still need to use await
in order to avoid race conditions.
Your full code queues up the following I/O operations:
The only restrictions on the ordering of these operations is that #1 must occur before #2, and #3 must occur before #4.
The order that these are completing in is: #1, #3, #2, #4
Because both findSimilar
calls complete before either insertListing
completes, they both return no match.
You should use async
, like so:
let test = async () => {
await storeListing({ buildingType:'MFH' });
await storeListing({ buildingType:'MFH' });
};
This enforces a new restriction on the operation order: that #2 must occur before #3