spring-projects / spring-integration

Spring Integration provides an extension of the Spring programming model to support the well-known Enterprise Integration Patterns (EIP)
http://projects.spring.io/spring-integration/
Apache License 2.0
1.54k stars 1.1k forks source link

Add Reactive Stream and Kotin Coroutines Support for Distributed Locks #8630

Open hantsy opened 1 year ago

hantsy commented 1 year ago

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.

artembilan commented 1 year ago

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 commented 1 year ago

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

artembilan commented 1 year ago

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...

hantsy commented 1 year ago

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 commented 1 year ago

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.

artembilan commented 1 year ago

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!

hantsy commented 1 year ago

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

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

artembilan commented 1 year ago

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...

hantsy commented 1 year ago

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).

muscidaes commented 10 months ago

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.