I have a spring application which can run in a clustered environment. In that environment I use Redis (and Redisson) as a distributed lock-service.
Many of the locks are used to e.g. protect certain tasks which can only run once at a time, or which may only be started every X seconds.
The application is also capable of running in standalone mode (without redis).
However for this case I need a different implementation of the lockservice. I thought this would be extremely simple because I only need to create a Lock instance locally with a certain timeout (e.g. for the "only run action at most ever 2 minutes"). However when looking around I could not find any implementation of the Java Lock interface which supports setting a timeout for the lock (so that it automatically unlocks itself after that time).
Is there such a thing, or is there an extremely simple (in terms of lines-of-code) way how I can implement this myself, which I'm just missing?
How that lock impl should behave:
- Other threads are not able to lock it while it's active (as any other lock)
- Ideally, the owning thread should be able to call lock(long timoutMs) again to extend the lock (set the timeout to the given time again)
EDIT: It seems that a concrete example could help understand what I am looking for:
- Imagine the server has an HTTP action "doExpesiveTask"
- whenever this task is called, my application goes to its ockService" and calls
.tryAcquireLock("expensiveTaskId", 10, TimeUnit.Minutes)
and gets back a boolean if it got the lock or not. - if it got the lock it starts the task
- if it didn't get the lock it doesn't and shows the user "you have to be more patient"
In a distributed setup the implementation of the lockService
uses redis (and the Redisson library) distributed locks (this already works great)!
To have a very simple switch between distributed and standalone mode, I simply want to have an implementation of lockService
which doesn't rely on any external service. Therefore I would simply need an implementation of a Lock which supports a timeout. With that I could simply have a ConcurrentHashMap inside the lockservice which maps lock-ids to these lock instances.
Why not simply use a Map that maps lock-ids to time-objects: because I also need to prevent other threads from re-locking (extending the lifetime) of a lock which was acquired by another thread.