1c5e9845 days ago32 lines · 968 B| 1 | /** Runs work once per key at a time; a call while it runs queues exactly one rerun after it, so the last call's state always gets seen. */ |
| 2 | export class Coalescer |
| 3 | private readonly running |
| 4 | private readonly rerun |
| 5 | |
| 6 | run(key: |
| 7 | const running = |
| 8 | if (running) { |
| 9 | this.rerun.add |
| 10 | return running; |
| 11 | } |
| 12 | |
| 13 | const run = |
| 14 | do { |
| 15 | this.rerun.delete |
| 16 | await work(); |
| 17 | } while (this. |
| 18 | })().finally(() |
| 19 | this.running.set |
| 20 | return run; |
| 21 | } |
| 22 | |
| 23 | isRunning(key: |
| 24 | return this.running |
| 25 | } |
| 26 | |
| 27 | /** Drops a queued rerun and resolves once the run in flight, if any, has finished. */ |
| 28 | async settle(key |
| 29 | this.rerun.delete |
| 30 | await this.running |
| 31 | } |
| 32 | } |