You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Disposable interface defines the void dispose() method, which is of eager nature and in most cases assumes non graceful, forceful release of underlying resources. There are cases where such an attempt is not desired. Other projects, like reactor-netty, or rsocket-java, have come up with their own abstractions for disposing resources related to connection and request management. In reactor-core, it was also necessary to support graceful disposal of implementations of Scheduler interface (#3089).
Desired solution
It looks that from the existing implementations, the following properties are desired:
lazily triggered
graceful (allows cleanup and timely termination of allocated resources)
observable and coordinated result
supports timeout and forceful termination in case the deadline passes
can support more timeout conditions, e.g. in case of reactor-netty there are two timeout values with different meanings
I would argue it's possible to unify these efforts using following methods:
Mono<Void> disposeGracefully() as part of a new Disposable.Graceful interface,
Mono<Void> onDispose() potentially added to Disposable (breaking change) or a new interface, e.g. ListenableDisposable, which would become a parent of Disposable.Graceful.
The current Disposable already has
void dispose()
boolean isDisposed()
Together, they would form a base for extension using concepts specific to a particular use case, e.g. the quietPeriod and deadline in case of reactor-netty, could be expressed as Mono<Void> disposeGracefully(Duration deadline, Duration quietPeriod).
Considered alternatives
One alternative would be to assume different use cases have different needs and the unification effort is pointless. However, without a common denominator, the existing APIs differ even within the same project, potentially leading to inconsistencies and lack of easy-to-predict behaviors.
The text was updated successfully, but these errors were encountered:
Motivation
Disposable
interface defines thevoid dispose()
method, which is of eager nature and in most cases assumes non graceful, forceful release of underlying resources. There are cases where such an attempt is not desired. Other projects, like reactor-netty, or rsocket-java, have come up with their own abstractions for disposing resources related to connection and request management. In reactor-core, it was also necessary to support graceful disposal of implementations ofScheduler
interface (#3089).Desired solution
It looks that from the existing implementations, the following properties are desired:
To list some examples:
reactor-netty in
DisposableChannel
:Disposable#dispose()
: https://github.com/reactor/reactor-netty/blob/f1f44ae9d39d3321aa9b90c90e36a2720ce9838f/reactor-netty-core/src/main/java/reactor/netty/DisposableChannel.java#L70disposeNow()
anddisposeNow(Duration)
blocking methods that delegate to the forcefuldispose()
: https://github.com/reactor/reactor-netty/blob/f1f44ae9d39d3321aa9b90c90e36a2720ce9838f/reactor-netty-core/src/main/java/reactor/netty/DisposableChannel.java#L89Mono<Void> onDispose()
method: https://github.com/reactor/reactor-netty/blob/f1f44ae9d39d3321aa9b90c90e36a2720ce9838f/reactor-netty-core/src/main/java/reactor/netty/DisposableChannel.java#L127reactor-netty in
LoopResources
:Disposable#dispose()
method: https://github.com/reactor/reactor-netty/blob/cc9aeb2901ed6f727e3e3d5c6bb604d3a3daa1ac/reactor-netty-core/src/main/java/reactor/netty/resources/LoopResources.java#L167Mono<Void> disposeLater()
that delegates toMono<Void> disposeLater(Duration quietPeriod, Duration timeout)
with some default timeout values inLoopResources
: https://github.com/reactor/reactor-netty/blob/cc9aeb2901ed6f727e3e3d5c6bb604d3a3daa1ac/reactor-netty-core/src/main/java/reactor/netty/resources/LoopResources.java#L178Mono<Void> disposeLater()
inConnectionProvider
and lazily implements it inPooledConnectionProvider
: https://github.com/reactor/reactor-netty/blob/0497c91cc093a3ee04855c77434bd40e7d8c7300/reactor-netty-core/src/main/java/reactor/netty/resources/PooledConnectionProvider.java#L186disposeGracefully(Duration)
from reactor-pool (https://github.com/reactor/reactor-pool/blob/5369c64527c4bf4c94d0c3a301236420e5c7af09/src/main/java/reactor/pool/decorators/GracefulShutdownInstrumentedPool.java#L53), which provides a timeout and utilities over thedisposeLater()
fromPool
: https://github.com/reactor/reactor-pool/blob/6e50a6fa82872bc5fe76a7821989de4359e376e5/src/main/java/reactor/pool/Pool.java#L172rsocket-java uses the
DisposableChannel
from reactor-netty with its ownCloseable
interface:Mono<Void> onClose()
method is the essence of theCloseable
interface which allows listening for terminationCloseableChannel
delegates to thedispose()
method ofDisposableChannel
: https://github.com/rsocket/rsocket-java/blob/c80b3cb6437046f3ccc79136a66299448f58c561/rsocket-transport-netty/src/main/java/io/rsocket/transport/netty/server/CloseableChannel.java#L74onDispose()
fromonClose()
: https://github.com/rsocket/rsocket-java/blob/c80b3cb6437046f3ccc79136a66299448f58c561/rsocket-transport-netty/src/main/java/io/rsocket/transport/netty/server/CloseableChannel.java#L84I would argue it's possible to unify these efforts using following methods:
Mono<Void> disposeGracefully()
as part of a newDisposable.Graceful
interface,Mono<Void> onDispose()
potentially added toDisposable
(breaking change) or a new interface, e.g.ListenableDisposable
, which would become a parent ofDisposable.Graceful
.The current
Disposable
already hasvoid dispose()
boolean isDisposed()
Together, they would form a base for extension using concepts specific to a particular use case, e.g. the quietPeriod and deadline in case of reactor-netty, could be expressed as
Mono<Void> disposeGracefully(Duration deadline, Duration quietPeriod)
.Considered alternatives
One alternative would be to assume different use cases have different needs and the unification effort is pointless. However, without a common denominator, the existing APIs differ even within the same project, potentially leading to inconsistencies and lack of easy-to-predict behaviors.
The text was updated successfully, but these errors were encountered: