Last active
December 1, 2018 16:17
-
-
Save zerobias/6de214b9280917fe5fd9c537b7ab308c to your computer and use it in GitHub Desktop.
Mutex
This file contains hidden or 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
/* @flow */ | |
class Lock { | |
release: () => void | |
sustain = new Promise<void>(resolve => { | |
this.release = resolve | |
}) | |
} | |
export type Releaser<Key> = Promise<() => void> | |
export class LockPack<Key> { | |
lockPromises: Map<Key, Promise<void>> = new Map() | |
RELEASER_KEY = Symbol('releaser key') | |
cleanup(releaser: Releaser<Key>) { | |
this.lockPromises.delete((releaser: any)[this.RELEASER_KEY]) | |
} | |
/** | |
* Acquires a mutex lock over the given key. If the lock can't be acquired, it waits until it's available. | |
* @param key Key to get the lock for. | |
* @return {Promise.<() => void>} A Promise that resolves when the lock is acquired, with the function that | |
* must be called to release the lock. | |
*/ | |
lock(key: Key): Releaser<Key> { | |
const lock = new Lock() | |
const lockPromise = this.lockPromises.get(key) || Promise.resolve() | |
const releaser = lockPromise.then(() => lock.release) | |
const sustain = lockPromise.then(() => lock.sustain) | |
this.lockPromises.set(key, sustain) | |
;(releaser: any)[this.RELEASER_KEY] = key | |
return releaser | |
} | |
} | |
export default new LockPack<any>() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment