Skip to content

Instantly share code, notes, and snippets.

@CMCDragonkai
Created September 28, 2021 03:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CMCDragonkai/9143920a47499f8a42f21ce46102a8b5 to your computer and use it in GitHub Desktop.
Save CMCDragonkai/9143920a47499f8a42f21ce46102a8b5 to your computer and use it in GitHub Desktop.
Concurrently Coalesced Asynchronous Construction #typescript
import { Mutex, MutexInterface } from 'async-mutex';
type ObjectId = string;
type Object = number;
type ObjectMap = Map<ObjectId, {
object?: Object;
lock: MutexInterface;
}>;
const objects: ObjectMap = new Map();
async function createObject(): Promise<Object> {
// possibly throw an exception here
return 1;
}
async function getObject(objectId: ObjectId): Promise<Object> {
let object: Object | undefined;
let lock: MutexInterface;
let objectAndLock = objects.get(objectId);
if (objectAndLock != null) {
({ object, lock } = objectAndLock);
if (object != null) {
console.log('ACQUIRED FROM EXISTING');
return object;
}
let release;
try {
release = await lock.acquire();
({ object, lock } = objectAndLock);
if (object != null) {
console.log('ACQUIRED FROM WAITING');
return object;
}
object = await createObject();
objectAndLock.object = object;
console.log('CREATED FROM WAITING');
return object;
} finally {
release();
}
} else {
lock = new Mutex();
objectAndLock = { lock };
objects.set(objectId, objectAndLock);
let release;
try {
release = await lock.acquire();
object = await createObject();
objectAndLock.object = object;
console.log('CREATED FROM NOT EXISTING')
return object;
} finally {
release();
}
}
}
async function main () {
const os = await Promise.all([
getObject('someobject1'),
getObject('someobject1'),
getObject('someobject2'),
getObject('someobject2'),
]);
console.log(os);
await getObject('someobject1');
await getObject('someobject2');
}
main();
@CMCDragonkai
Copy link
Author

Should be refactored. Seems like the CREATED FROM NOT EXISTING should be on top, as that is likely the first thing to do.

Then the second part is dealing with potentially something that is already created or in the midst of creation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment