use of io.servicetalk.concurrent.api.AsyncCloseable in project servicetalk by apple.
the class ChannelSet method closeAsyncGracefully.
@Override
public Completable closeAsyncGracefully() {
return new SubscribableCompletable() {
@Override
protected void handleSubscribe(final Subscriber subscriber) {
if (!stateUpdater.compareAndSet(ChannelSet.this, OPEN, GRACEFULLY_CLOSING)) {
toSource(onClose).subscribe(subscriber);
return;
}
if (channelMap.isEmpty()) {
toSource(onClose).subscribe(subscriber);
onCloseProcessor.onComplete();
return;
}
CompositeCloseable closeable = newCompositeCloseable();
for (final Channel channel : channelMap.values()) {
Attribute<PrivilegedListenableAsyncCloseable> closeableAttribute = channel.attr(CHANNEL_CLOSEABLE_KEY);
PrivilegedListenableAsyncCloseable channelCloseable = closeableAttribute.getAndSet(null);
if (null != channelCloseable) {
// Upon shutdown of the set, we will close all live channels. If close of individual channels
// are offloaded, then this would trigger a surge in threads required to offload these closures.
// Here we assume that if there is any offloading required, it is done by offloading the
// Completable returned by closeAsyncGracefully() hence offloading each channel is not required.
// Hence, we use the "noOffload" variant for each channel for this particular subscribe to use
// immediate and effectively disable offloading on each channel.
closeable.merge(new AsyncCloseable() {
@Override
public Completable closeAsync() {
return channelCloseable.closeAsyncNoOffload();
}
@Override
public Completable closeAsyncGracefully() {
return channelCloseable.closeAsyncGracefullyNoOffload();
}
});
} else {
channel.close();
}
}
closeable.append(() -> onClose);
toSource(closeable.closeAsyncGracefully()).subscribe(subscriber);
}
};
}
Aggregations