Skip to content

Instantly share code, notes, and snippets.

@freddi301
Created June 20, 2016 17:04
Show Gist options
  • Save freddi301/01fae80684c32425babc09e5f5e28f61 to your computer and use it in GitHub Desktop.
Save freddi301/01fae80684c32425babc09e5f5e28f61 to your computer and use it in GitHub Desktop.
Optimistic Loop Mongo Node + throng
import throng from 'throng';
import {MongoClient} from 'mongodb';
let dups = 0;
async function insertOptimisticLoop(doc, collection, retry=100){
const cursor = await collection // find greatest __t progrssive number
.find( { __t: { $exists: true } }, { __t: 1, __id: -1} )
.sort( { __t: -1 } ).limit(1);
const next = await cursor.hasNext() ? (await cursor.next()).__t + 1 : 1; // calculate next __t
doc.__t = next;
let result; try { result = await collection.insert(doc); } catch (error) {
if( error.code == 11000 /* dup key */ ) {
dups++;
return new Promise((resolve,reject)=>setTimeout(()=>resolve(
insertOptimisticLoop(doc, collection, retry*(Math.random()+1)))
, retry));
}
else console.error(error);
}
return result;
}
throng(async function(workerNo){
console.log('worker', workerNo, 'up');
const db = await MongoClient.connect('mongodb://localhost:27017/test')
const collection = db.collection('test');
await collection.ensureIndex({__t: 1}, {name: '__t', unique: true});
await Promise.all([insertOptimisticLoop({workerNo, x: 1}, collection),
insertOptimisticLoop({workerNo, x: 2}, collection),
insertOptimisticLoop({workerNo, x: 3}, collection),
insertOptimisticLoop({workerNo, x: 4}, collection),
insertOptimisticLoop({workerNo, x: 5}, collection),
insertOptimisticLoop({workerNo, x: 6}, collection),
insertOptimisticLoop({workerNo, x: 7}, collection),
insertOptimisticLoop({workerNo, x: 8}, collection),
insertOptimisticLoop({workerNo, x: 9}, collection),
insertOptimisticLoop({workerNo, x: 10}, collection)]);
await db.close();
console.log('worker', workerNo, 'finish', dups);
})//(1).then(()=>process.exit(0))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment