Implementing Write Throttling / Back pressure
See original GitHub issueThis is more of a design question on what is the correct way to implement Write Throttling / Back pressure, so that we don’t continue writing to a channel when isWritable
flag returns false.
I have added the High and Low WaterMarks to control when exactly this flag should return false.
looking at @normanmaurer 's answer on SO for this issue :
You are writing faster then the network stack can handle. Be aware it’s all asynchronous… You want to stop writing once Channel.isWritable() returns false and resume once it returns true again. You can notified for this changes by override the channelWritabilityChanged(…) method in ChannelInboundHandler.
What I have tried in order to stop writing when Channel.isWritable()
returns false and resume when it returns true, is to block on the event loop thread while checking for the flag in a loop. This is not ideal since the event loop thread is blocked. What would be the correct way to do achieve throttling/back pressure handling ? . Any help is much appreciated.
Relevant code snippets.
Listening to channel writability changed and unlocking
public void channelWritabilityChanged(ChannelHandlerContext ctx)
throws Exception {
Channel channel = ctx.channel();
ThrottleLock throttleLock = channel.attr(THROTTLE_LOCK_KEY).get();
if (channel.isWritable()) {
synchronized (throttleLock) {
throttleLock.notifyAll();
}
}
ctx.fireChannelWritabilityChanged();
}
waiting and blocking to see if the channel is writable
ThrottleLock throttleLock = channel.attr(THROTTLE_LOCK_KEY).get();
synchronized (throttleLock) {
while (!channel.isWritable()) {
throttleLock.wait(TimeUnit.MILLISECONDS.toMillis(100));
}
channel.writeAndFlush(request);
}
Netty Version
4.1.29.Final
Java Version
java version “1.8.0_192” Java™ SE Runtime Environment (build 1.8.0_192-b12) Java HotSpot™ 64-Bit Server VM (build 25.192-b12, mixed mode)
Issue Analytics
- State:
- Created 3 years ago
- Comments:7 (2 by maintainers)
Top GitHub Comments
@ajaygeorge basically you need to stop writing unit the channel becomes writable again. You will be notified once the writability state of the
Channel
changes via theChannelInboundHandler.channelWritabilityChanged(...)
callback. Once this happens you can start writing again. How you propagate this though your application / framework, is up to you. Just never block the event loop.Thanks @johnou . Looking at that PR , it seems like trustin had some concerns over the implementation which I believe was the reason why it was not merged. As the PR description suggests this for implementing back-pressure to stop reading from a socket.
In my case, the backpressure handling is needed for writes to a remote peer (not running netty) from a local client (running netty)