Skip to content

Instantly share code, notes, and snippets.

@CMCDragonkai
Created October 5, 2021 03:58
Show Gist options
  • Save CMCDragonkai/f58f08e7eaab0430ed4467ca35527a42 to your computer and use it in GitHub Desktop.
Save CMCDragonkai/f58f08e7eaab0430ed4467ca35527a42 to your computer and use it in GitHub Desktop.
Singleton Object Map using Locking #typescript #javascript
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();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment