Created
September 28, 2021 03:45
-
-
Save CMCDragonkai/9143920a47499f8a42f21ce46102a8b5 to your computer and use it in GitHub Desktop.
Concurrently Coalesced Asynchronous Construction #typescript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
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.