-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom TTL per LOCK in LockRegistry #3444
Comments
See more info here: #3095. We probably really talk about the same matter - Not sure if we can do it for the current WDYT? |
@artembilan Thanks. Yes, I think we are on the same page! I call it TTL here because it is named TTL in the code of current implementation of /**
* Specify the time (in milliseconds) to expire dead locks.
* @param timeToLive the time to expire dead locks.
*/
public void setTimeToLive(int timeToLive) {
this.ttl = timeToLive;
} What I noticed is that in the mentioned issue you decide to introduce a new method My suggestion here is to modify (or, more specifically, overload) public Lock obtain(Object lockKey, Duration ttl) {
String path = pathFor((String) lockKey);
return this.locks.computeIfAbsent(path, (key) -> new JdbcLock(this.client, this.idleBetweenTries, key, ttl)); // note new TTL argument here
} And because TTL is not absolute instant of time, but relative value, it should work even if you trying to I also discovered #3272 just now and see that my second "workaround" is already implemented in |
By the way, if this feature will be implemented, it would be better to change "renew" implementation to update new Actually, this not only desirable, but required, because new "expiration query" will have to delete expired locks based on Looks, like |
I think we applied the renewal logic on the My point against Does it make sense? |
Yes, I think it does make sense. You are talking about the situation when obtained I just didn't thought about it this way. In my mind the relationship between But then, it looks like |
Yes, that makes sense. Thanks. We have renewal contract on the registry at the moment because of to big breaking change with a new Feel free to fork the project and try something yourself! we also can review small PRs even if the feature is not complete yet or can't make it into the current version. |
Any news on this enhancement? |
See my previous comment:
So, we are going to tackle this in the next |
@artembilan Any news on this issue ? version version 6.0 is about to be release right ? |
No, we didn't have a chance to look into this. Feel free to contribute some if you'd like. Thank you for understanding! |
…cLock Fixes: spring-projects#3444 * add `CustomTtlLock`, and `CustomTtlLockRegistry` interfaces * Modify `RedisLockRegistry` to implement the interfaces. * Modify `JdbcLockRegistry` to implement the interfaces. * Modify `unlock` method of `JdbcLock` to prevent potential concurrency issue. * Maintain existing test cases and add new test cases.
…cLock Fixes: spring-projects#3444 * add `CustomTtlLock`, and `CustomTtlLockRegistry` interfaces * Modify `RedisLockRegistry` to implement the interfaces. * Modify ddl of `INT_LOCK` table, `LockRepository`, `DefaultLockRepository`, and `JdbcLockRegistry` to implement the interfaces. * Fix potential concurrency issue of `unlock` method of `JdbcLock`. * Maintain existing test cases and add new test cases.
…cLock Fixes: spring-projects#3444 * Add `CustomTtlLock`, and `CustomTtlLockRegistry` interfaces * Modify `RedisLockRegistry` to implement the interfaces. * Modify ddl of `INT_LOCK` table, `LockRepository`, `DefaultLockRepository`, and `JdbcLockRegistry` to implement the interfaces. * Fix potential concurrency issue of `unlock` method of `JdbcLock`. * Maintain existing test cases and add new test cases.
…cLock Fixes: spring-projects#3444 * Add `CustomTtlLock`, and `CustomTtlLockRegistry` interfaces * Modify `RedisLockRegistry` to implement the interfaces. * Modify ddl of `INT_LOCK` table, `LockRepository`, `DefaultLockRepository`, and `JdbcLockRegistry` to implement the interfaces. * Fix potential concurrency issue of `unlock` method of `JdbcLock`. * Maintain existing test cases and add new test cases.
Current default (and only) implementation of
LockRepository
based on JDBC (DefaultLockRepository
) allows to set static TTL for all locks, controlled by this repository.But not all locks are equal. Some locks require bigger TTL than others. It would be good to support custom TTL per lock.
From DB point of view, I think this is easy task. Currently DB stores
CREATED_DATE
field. If newEXPIRATION_DATE
field will be added to the table, it would be easy to expire records based on this date instead of date of creation + TTL.From repository point of view it is not so easy. It requires to change the interface or create a new interface that extends current
LockRepository
and adds new method:From registry point of view it is not so easy too. The only method of
LockRegistry
allows to obtain a lock only usinglockKey
(Lock obtain(Object lockKey)
). But to support custom TTL per Lock we need to add another method, like:that would set an explicit TTL on
JdbcLock
. AndJdbcLock
then will pass this TTL into it'sLockRepository
fromdoLock()
method.So, for JDBC implementation it looks totally possible to implement.
But I didn't investigate other implementations of
LockRepository
andLockRegistry
(not based on JDBC). I'm not familiar with Redis or Zookeeper, so it would be good if someone first evaluate the idea of this feature request.Context
Not all business processes are the same. Some usually finish in 2 secs. Other in 20 mins. So, having a static TTL for all locks of repository is impractical. Setting it to intentionally big value is impractical too, as this means that fast business process, that is killed before lock release, will not be restarted until this big TTL ends.
The workaround to this problem is to use multiple instances of
LockRepository
(and wrappingLockRegistry
) with multiple differentINT_LOCK
tables. In this case each instance ofLockRepository
can be configured with explicit TTL. This is only partial workaround as it's hard to predict all possible TTLs for each possible business process. But it cloud be generalized to, say, 3 tables (with TTL=10 secs, 10 mins and 10 hours).The other workaround, I think, is to periodically call
lock()
methods again on currently held lock. As I see in the code, it should update theCREATED_DATE
field in the table to current datetime, so expiration date will be prolonged too. I actually think, this is the best approach, as it allows to not set too long TTL and at the same time to not mistakenly acquire the lock, that other process still holds.But it's not always easy to implement this in business logic. For example, if some external service is called with big timeout (and if timeout must be big for this service for some reason) and this external service usually responds in 2 secs, but sometimes in 2 mins. In this case, calling thread is blocked until external service respond or timeout is reached, so no
lock()
method could be called again in this timeframe.The text was updated successfully, but these errors were encountered: