spring-integration icon indicating copy to clipboard operation
spring-integration copied to clipboard

Add Reactive Stream and Kotin Coroutines Support for Distributed Locks

Open hantsy opened this issue 2 years ago • 10 comments

Currently I am working on a Spring WebFlux/Kotlin Coroutines/R2dbc project, tried to use Spring Integration Locks, but found it only supports the legacy jdbc etc. But do not R2dbc.

If possible to add an Reactive and Kotlin Coroutines alternative to the existing LockRegistry.

  • ReactiveLockRegistry
  • CoroutinesLockRegistry(Spring Data naming for Kotlin Coroutines) or CoLockRegistry(Spring framework naming for Kotlin Coroutines)

hantsy avatar May 23 '23 04:05 hantsy

I'm sorry it is not fully clear what you mean. Would you mind to share with us much more info how that supposed to look from end-user perspective? The regular Lock pattern is like this:

 Lock l = ...;
 l.lock();
 try {
    // access the resource protected by this lock
 } finally {
    l.unlock();
 }

So, we have a scope which is blocked for others.

How that might look from a reactive streams perspective? More over the LockRegistry delegates to the regular ReentrantLock therefore there is a barrier against the thread executing that scoped block of code. Apparently we cannot use Java lock primitive for reactive streams since there is no guarantee that publishing happens on the same thread.

Well, just give us more info about your idea.

P.S. I believe you made a mistake in your post: ReactiveLogRegistry -> ReactiveLockRegistry

artembilan avatar May 23 '23 13:05 artembilan

This is probably your SO question: https://stackoverflow.com/questions/76315192/redislockregistry-with-webflux-and-kotlin

artembilan avatar May 23 '23 15:05 artembilan

OK. So, I see there is a nice Mutex abstraction for lock in Kotlin Coroutines: https://kotlinlang.org/docs/shared-mutable-state-and-concurrency.html#mutual-exclusion.

I guess it is now just a matter of a proper impl of this Mutex against respective Reactive library, e.g. R2dbcEntityOperations.

With Reator's Flux and Mono it is probably going to be a bit involved...

artembilan avatar May 23 '23 17:05 artembilan

I know the Mutex, what I need is a distributed lock implementation.

In a Spring WebFlux project, when using R2dbc to do RDBMS operations, I am eager there is a R2dbc implementation of the LockRegistry instead of Jdbc version.

hantsy avatar May 24 '23 02:05 hantsy

This is probably your SO question: https://stackoverflow.com/questions/76315192/redislockregistry-with-webflux-and-kotlin

It is not my question(my SO account is hantsy), but we have similar requirements in our real world project.

hantsy avatar May 24 '23 02:05 hantsy

Right. That’s why I’m asking: give me a sample how end-user API suppose to look like. Or even better: take an opportunity and contribute this feature!

artembilan avatar May 24 '23 02:05 artembilan

There are some open source reactive lock implementation project using the Reactor project,

  • https://github.com/chenggangpro/reactive-lock
  • https://github.com/gudzpoz/reactor-locks
  • https://github.com/alex-pumpkin/reactor-lock

But they lacks a reactive LockRegistry abstract to apply in a cluster environment.

hantsy avatar May 24 '23 02:05 hantsy

How so? I see there this one: https://github.com/chenggangpro/reactive-lock/blob/main/src/main/java/pro/chenggang/project/reactive/lock/core/redis/RedisReactiveLockRegistry.java. Therefore they do support already something what you'd like. Only what we (they?) need is really your request for R2DBC. Probably you can implement it yourself modeling it after that Redis one.

The problem with those libraries that they are personal, single-person projects and looks like they are a bit out-dated anyway. Therefore we cannot accept them as dependencies to develop our own distributed lock registries.

If we really want to go this direction I'd suggest to raise a separate issue for Kotlin Kotlin Coroutines where impl would be fully different than Reactor one and based on the mentioned kotlinx.coroutines.sync.Mutex abstraction to be used idiomatically in Kotlin style:

            // protect each increment with lock
            mutex.withLock {
                counter++
            }

For Mono I will need to discuss with reactor team what is our best way to go...

artembilan avatar May 24 '23 15:05 artembilan

For Mono I will need to discuss with reactor team what is our best way to go...

It is great.

Spring introduce Reactive stack since 5.0, I just hope all Spring subprojects are aligned to reactive stack, thus when starting a Spring reative project, as a developer we will use the reactive APIs smoothly without gaps(I mean some features only support traditional blocking API).

hantsy avatar May 25 '23 01:05 hantsy

Nice work, That's what I've been having trouble with lately, but I can't find a solution on the Internet, and Redission doesn't support locking in webflux.

muscidaes avatar Nov 08 '23 16:11 muscidaes