Skip to content
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

Whether to consider adding capability to wait to acquire lock #1223

Open
Yannis-01 opened this issue Nov 4, 2022 · 3 comments
Open

Whether to consider adding capability to wait to acquire lock #1223

Yannis-01 opened this issue Nov 4, 2022 · 3 comments

Comments

@Yannis-01
Copy link

now, if cant get lock , will do nothing. whether to consider adding capability to wait lock

@lukas-krecan
Copy link
Owner

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.

@KSH-code
Copy link

KSH-code commented Feb 9, 2023

👍

@TheBestPessimist
Copy link

TheBestPessimist commented Oct 31, 2023

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")
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants