Whether to consider adding capability to wait to acquire lock
now, if cant get lock , will do nothing. whether to consider adding capability to wait lock
Hi, thanks for feedback. The best way you can do it is to wrap LockProvider and do it yourself. You can create your own implementation of LockProvider, wrap the original one and if its lock method returns an empty Optional, you can sleep for a while and try again.
:+1:
Do you have any code which does this already? I'd like to use this functionality too!
What i have done is a custom LockProvider which is used in a single class, where i need it, while the normal LockProvider is autowired by spring for every annotated function. Even though it seems to work, the way I implemented it feels so wrong.
Here's my implementation, along with a Spring Boot test which demonstrates it:
class AllCallsAreSerializedLockProvider(private val lockProvider: LockProvider) : LockProvider {
override fun lock(lockConfiguration: LockConfiguration): Optional<SimpleLock> {
var lockObtained: Optional<SimpleLock>
do {
lockObtained = lockProvider.lock(lockConfiguration)
if (lockObtained.isEmpty) TimeUnit.MILLISECONDS.sleep(10)
else break
} while (true)
return lockObtained
}
}
class TestAllCallsAreSerializedLockProvider : BaseIntegrationTest() {
@Autowired
lateinit var lockProvider: LockProvider
val lockExecutorutor: LockingTaskExecutor by lazy { DefaultLockingTaskExecutor(AllCallsAreSerializedLockProvider(lockProvider)) }
val executor = Executors.newFixedThreadPool(64)
@Test
fun `test lock from multiple tests`() {
val blockToExecute: Callable<Unit> = Callable { theFunctionWhichHasAlock() }
val tasks = List(15) { blockToExecute }
val responses = executor.invokeAll(tasks).map { it.get() }
println(responses)
}
fun theFunctionWhichHasAlock() {
val aa = Random().nextInt(64)
println("before lock $aa")
lockExecutorutor.executeWithLock(
Runnable {
println("work start $aa")
TimeUnit.SECONDS.sleep(10)
println("work end $aa")
},
LockConfiguration(/*createdAt*/ Instant.now(), /*name*/ "lockName", /*lockAtMostFor*/ 1.minutes.toJavaDuration(), /*lockAtLeastFor*/ 1.seconds.toJavaDuration()),
)
println("after lock $aa")
}
}