node-redlock
node-redlock copied to clipboard
#82: Implement custom delay strategy support
Issue: https://github.com/mike-marcacci/node-redlock/issues/82
@mike-marcacci Sketch implementation of custom retry strategy. I've though about few options & decided to go with Strategy option since I decided to minimise changes to lock code, and best approach looked like this to me:
export interface RetryStrategy {
getRetryCount: () => number;
getRetryDelay: (attemptNumber: number) => number;
}
After reviewing implementation I had a second thought that it can be simplified with just passing some retryDelays: Array<number>
parameter to config directly, and instead of strategy as object use function to generate arbitrary delay values.
e.g:
const redlock = new Redlock( ... {
retryDelays: exponentialDelays({ startDelay: 200, expFactor: 2, maxDelay: 1000, retryCount: 5 })
});
being just passing an array:
const redlock = new Redlock( ... {
retryDelays: [200, 400, 800, 1000, 1000]
});
It feels to me that it's even better considering overall node-redlock
strive to simplicity 👍 Waiting for feedback.
Just a thought of mine. A pre-defined array may not satisfy if infinite retries are demanded. An iterator/generator may be more suitable in this case.
@onichandame I'm not sure that infinite retry is safe - since many clients can compete for acquiring a locks (e.g. you get a large burst of concurrent requests for single resource), you may end up with indeterministic time. Basically service may stop waiting for lock for unknown period of time, but you won't notice that. With fixed retry count there is a guaranty that lock will be either acquired or failed in some limited time.
@meredian I agree that infinite retries are not desirable in most cases. Forgive my bad example, my main point is that iterators offer many more possibilities than a static array. Another example would be exponential delay, where the delay period is dependent on the previous one. With iterators it can be done simply:
function *getDelay(){
let count=0;
while (count < 5)
yield 2 ** (count ++)
}
const redlock = new Redlock( ... {
retryDelays: getDelay()
});
The logic here is more clear and maintainable than giving an expanded array.