swarthy / redis-semaphore

Distributed mutex and semaphore based on Redis
MIT License
148 stars 28 forks source link

Behavior changed for `externallyAcquiredIdentifier` after 5.3.1 #193

Closed AngelMsger closed 6 months ago

AngelMsger commented 1 year ago

Hi, thank you for your awesome lib!

I used to use the externallyAcquiredIdentifier option of Mutex to implement a reentrant distributed lock. That's to say, if multi locks have the same identifier, they will be treated as the same lock holder. It is convenient because there are many complex scenarios I don't want to add a lock state argument to all my functions involved and pass through everywhere. Instead, I can use transaction id as an identifier to indicate that if the mutex has been acquired by the outer stack frame, just go through. This is an example test case:

test('reentrant', async ({ assert }) => {
    const identifier = randomUUID();
    const lock1 = new Mutex(redis, key, {
        // ...,
        externallyAcquiredIdentifier: identifier
    });
    const lock2 = new Mutex(redis, key, {
        // ...,
        externallyAcquiredIdentifier: identifier
    });
    assert.isTrue(await lock1.tryAcquire());
    assert.isTrue(await lock2.tryAcquire());
});

But it was broken at version 5.3.1 it this commit: https://github.com/swarthy/redis-semaphore/commit/3f704899b4f2dcd4e28233948cfe2b0c59bd07ee#diff-f30ff58349492ea4098fb2a9d1e13e5ea42c34b003959dc4d1e8a008bfcdf313

Is there any alternative or suggestion?

swarthy commented 6 months ago

Hi. Currently reentrant locks is not supported. This behaviour was not documented and unexpected for users https://github.com/swarthy/redis-semaphore/issues/175