-
-
Notifications
You must be signed in to change notification settings - Fork 541
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #81 from tulios/support-concurrent-broker-connect
Support concurrent broker connect
- Loading branch information
Showing
9 changed files
with
147 additions
and
16 deletions.
There are no files selected for viewing
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
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
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
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
const EventEmitter = require('events') | ||
const { KafkaJSError } = require('../errors') | ||
|
||
module.exports = class Lock { | ||
constructor({ timeout = 1000 } = {}) { | ||
this.locked = false | ||
this.timeout = timeout | ||
this.emitter = new EventEmitter() | ||
} | ||
|
||
async acquire() { | ||
return new Promise((resolve, reject) => { | ||
if (!this.locked) { | ||
this.locked = true | ||
return resolve() | ||
} | ||
|
||
let timeoutId | ||
const tryToAcquire = () => { | ||
if (!this.locked) { | ||
this.locked = true | ||
clearTimeout(timeoutId) | ||
this.emitter.removeListener('releaseLock', tryToAcquire) | ||
return resolve() | ||
} | ||
} | ||
|
||
this.emitter.on('releaseLock', tryToAcquire) | ||
timeoutId = setTimeout( | ||
() => reject(new KafkaJSError('Timeout while acquiring lock')), | ||
this.timeout | ||
) | ||
}) | ||
} | ||
|
||
async release() { | ||
this.locked = false | ||
setImmediate(() => this.emitter.emit('releaseLock')) | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
const waitFor = require('./waitFor') | ||
const flatten = require('./flatten') | ||
const Lock = require('./lock') | ||
|
||
const sleep = value => waitFor(delay => delay >= value) | ||
|
||
describe('Utils > Lock', () => { | ||
it('allows only one resource at a time', async () => { | ||
const lock = new Lock() | ||
const resource = jest.fn() | ||
const callResource = async () => { | ||
try { | ||
await lock.acquire() | ||
resource(Date.now()) | ||
await sleep(50) | ||
} finally { | ||
await lock.release() | ||
} | ||
} | ||
|
||
await Promise.all([callResource(), callResource(), callResource()]) | ||
const calls = flatten(resource.mock.calls) | ||
expect(calls.length).toEqual(3) | ||
expect(calls[1] - calls[0]).toBeGreaterThanOrEqual(50) | ||
expect(calls[2] - calls[1]).toBeGreaterThanOrEqual(50) | ||
}) | ||
|
||
it('throws an error if the lock cannot be acquired within a period', async () => { | ||
const lock = new Lock({ timeout: 60 }) | ||
const resource = jest.fn() | ||
const callResource = async () => { | ||
await lock.acquire() | ||
resource(Date.now()) | ||
await sleep(50) | ||
// it never releases the lock | ||
} | ||
|
||
await expect( | ||
Promise.all([callResource(), callResource(), callResource()]) | ||
).rejects.toHaveProperty('message', 'Timeout while acquiring lock') | ||
}) | ||
}) |
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