Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IllegalArgumentException in io.netty.util.internal.PriorityQueue #5980

Closed
rkapsi opened this issue Nov 4, 2016 · 26 comments
Closed

IllegalArgumentException in io.netty.util.internal.PriorityQueue #5980

rkapsi opened this issue Nov 4, 2016 · 26 comments
Assignees
Labels
Milestone

Comments

@rkapsi
Copy link
Member

rkapsi commented Nov 4, 2016

4.1.7-SNAPSHOT

It's always the same message: e.priorityQueueIndex(): 0 (expected: -1). It's strange because I don't see WeightedFairQueueByteDistributor$State#priorityQueueIndex(0) ever being called (or the priorityQueueIndex field getting set).

2016-11-04 13:12:14,722 [WorkerThread-2] ExceptionHandler ERROR: name=Http2ExceptionHandler, channel=[id: 0x020ee146, L:/aaa.aaa.aaa.aaa:443 - R:/bbb.bbb.bbb.bbb:63000]
 java.lang.IllegalArgumentException: e.priorityQueueIndex(): 0 (expected: -1)
	at io.netty.util.internal.PriorityQueue.offer(PriorityQueue.java:83) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.util.internal.PriorityQueue.offer(PriorityQueue.java:32) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.handler.codec.http2.WeightedFairQueueByteDistributor$State.offer(WeightedFairQueueByteDistributor.java:299) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.handler.codec.http2.WeightedFairQueueByteDistributor.distributeToChildren(WeightedFairQueueByteDistributor.java:198) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.handler.codec.http2.WeightedFairQueueByteDistributor.distribute(WeightedFairQueueByteDistributor.java:130) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.handler.codec.http2.DefaultHttp2RemoteFlowController$WritabilityMonitor.writePendingBytes(DefaultHttp2RemoteFlowController.java:631) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.handler.codec.http2.DefaultHttp2RemoteFlowController.writePendingBytes(DefaultHttp2RemoteFlowController.java:255) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.handler.codec.http2.Http2ConnectionHandler.flush(Http2ConnectionHandler.java:161) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.DefaultChannelPipeline.flush(DefaultChannelPipeline.java:974) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannel.flush(AbstractChannel.java:244) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at com.squarespace.echo.http2.streams.HttpToHttp2Handler.flush(HttpToHttp2Handler.java:71) [echo-http-2.17.16.jar:?]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:117) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:117) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:117) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelOutboundHandlerAdapter.flush(ChannelOutboundHandlerAdapter.java:115) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelOutboundHandlerAdapter.flush(ChannelOutboundHandlerAdapter.java:115) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelOutboundHandlerAdapter.flush(ChannelOutboundHandlerAdapter.java:115) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:117) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:117) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:117) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:117) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:117) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:117) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:117) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:117) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelOutboundHandlerAdapter.flush(ChannelOutboundHandlerAdapter.java:115) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:117) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:117) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:117) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.ChannelDuplexHandler.flush(ChannelDuplexHandler.java:117) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:787) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext.access$1500(AbstractChannelHandlerContext.java:39) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.AbstractChannelHandlerContext$16.run(AbstractChannelHandlerContext.java:767) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:418) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:454) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:873) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
	at java.lang.Thread.run(Thread.java:745) [?:1.8.0_102]
@normanmaurer
Copy link
Member

@Scottmitch @nmittler can you have a look ?

@Scottmitch
Copy link
Member

sure

@Scottmitch Scottmitch self-assigned this Nov 4, 2016
@Scottmitch
Copy link
Member

@rkapsi - can you tell me what your priority tree looks like when flush is invoked, and also do you have a reproducer?

priorityQueueIndex is set by our PriorityQueue implementation as nodes are inserted/removed and is to avoid the traversal for removal from the queue.

@rkapsi
Copy link
Member Author

rkapsi commented Nov 4, 2016

@Scottmitch I don't have a reproducer but it happens pretty reliably in our production environment. There is an initial burst as soon as the server starts accepting connections and then one every once in a while.

How do I get the info for the priority tree? ToString or do you need something else?

@rkapsi
Copy link
Member Author

rkapsi commented Nov 4, 2016

Just throwing it out there but could it be a thread visibility thing because priorityQueueIndex is neither final nor volatile?!

@Scottmitch
Copy link
Member

Scottmitch commented Nov 4, 2016

codec-http2 is not thread safe. You always have to be on the IO thread when ever you interact with it ... is this not the case in your setup?

@rkapsi
Copy link
Member Author

rkapsi commented Nov 4, 2016

Checking... Possible that my Http2ConnectionEncoder is called from a different thread.

@Scottmitch
Copy link
Member

Scottmitch commented Nov 4, 2016

I don't have a reproducer but it happens pretty reliably in our production environment.
How do I get the info for the priority tree? ToString or do you need something else?

If you are sure you are always on the I/O thread then it would be great to see the string represetnation of the general priority tree, and the string representation of the WeightedFairQueueByteDistributor's tree of queue's structure, when this issue occurs right before we call WeightedFairQueueByteDistributor#distribute. We don't have a means to serialize these to string now ... but they can be added if necessary.

@rkapsi
Copy link
Member Author

rkapsi commented Nov 4, 2016

@Scottmitch flush() and my interactions with the encoder are on the codec's IO thread.

Below are two toStrings() of the WeightedFairQueueByteDistributor's queue structure. I'm also attaching the code that was used to produce it. Where do I find the general priority queue?

2016-11-04 17:54:07,120 [WorkerThread-3] Http2HttpBridgeHandler ERROR: state=State{stream=0, queue=[State{stream=39, queue=[State{stream=41, queue=[State{stream=45, queue=[State{stream=47, queue=[State{stream=49, queue=[State{stream=51, queue=[State{stream=53, queue=[State{stream=55, queue=[State{stream=57, queue=[], streamableBytes=7453, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=0, pseudoTime=0, totalQueuedWeights=0, active=true}], streamableBytes=3158, activeCountForTree=2, priorityQueueIndex=0, pseudoTimeToWrite=0, pseudoTime=0, totalQueuedWeights=220, active=true}], streamableBytes=0, activeCountForTree=2, priorityQueueIndex=0, pseudoTimeToWrite=0, pseudoTime=0, totalQueuedWeights=220, active=false}], streamableBytes=6071, activeCountForTree=3, priorityQueueIndex=0, pseudoTimeToWrite=0, pseudoTime=0, totalQueuedWeights=220, active=true}], streamableBytes=0, activeCountForTree=3, priorityQueueIndex=0, pseudoTimeToWrite=0, pseudoTime=0, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=3, priorityQueueIndex=0, pseudoTimeToWrite=0, pseudoTime=0, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=3, priorityQueueIndex=0, pseudoTimeToWrite=57792, pseudoTime=0, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=3, priorityQueueIndex=0, pseudoTimeToWrite=62349, pseudoTime=62349, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=3, priorityQueueIndex=0, pseudoTimeToWrite=322177, pseudoTime=62349, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=3, priorityQueueIndex=-1, pseudoTimeToWrite=0, pseudoTime=322177, totalQueuedWeights=220, active=false}
2016-11-04 17:54:07,121 [WorkerThread-3] ExceptionHandler ERROR: name=Http2ExceptionHandler, channel=[id: 0x6dae7b41, L:/aaa.aaa.aaa.aaa:443 - R:/bbb.bbb.bbb.bbb:54938]
 java.lang.IllegalArgumentException: e.priorityQueueIndex(): 0 (expected: -1)
    at io.netty.util.internal.PriorityQueue.offer(PriorityQueue.java:83) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.util.internal.PriorityQueue.offer(PriorityQueue.java:32) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.handler.codec.http2.WeightedFairQueueByteDistributor$State.offer(WeightedFairQueueByteDistributor.java:299) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.handler.codec.http2.WeightedFairQueueByteDistributor.distributeToChildren(WeightedFairQueueByteDistributor.java:198) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.handler.codec.http2.WeightedFairQueueByteDistributor.distribute(WeightedFairQueueByteDistributor.java:130) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.handler.codec.http2.DefaultHttp2RemoteFlowController$WritabilityMonitor.writePendingBytes(DefaultHttp2RemoteFlowController.java:631) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.handler.codec.http2.DefaultHttp2RemoteFlowController.writePendingBytes(DefaultHttp2RemoteFlowController.java:255) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.handler.codec.http2.Http2ConnectionHandler.flush(Http2ConnectionHandler.java:161) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at com.squarespace.echo.http2.streams.Http2HttpBridgeHandler.flush(Http2HttpBridgeHandler.java:43) ~[echo-http-2.17.30.jar:?]
    at io.netty.handler.codec.http2.Http2ConnectionHandler.channelWritabilityChanged(Http2ConnectionHandler.java:385) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:445) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:427) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelWritabilityChanged(AbstractChannelHandlerContext.java:420) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.ChannelInboundHandlerAdapter.channelWritabilityChanged(ChannelInboundHandlerAdapter.java:119) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:445) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:427) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelWritabilityChanged(AbstractChannelHandlerContext.java:420) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.ChannelInboundHandlerAdapter.channelWritabilityChanged(ChannelInboundHandlerAdapter.java:119) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:445) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:427) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelWritabilityChanged(AbstractChannelHandlerContext.java:420) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.ChannelInboundHandlerAdapter.channelWritabilityChanged(ChannelInboundHandlerAdapter.java:119) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:445) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:427) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelWritabilityChanged(AbstractChannelHandlerContext.java:420) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelWritabilityChanged(DefaultChannelPipeline.java:1357) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:445) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:427) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.DefaultChannelPipeline.fireChannelWritabilityChanged(DefaultChannelPipeline.java:938) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.ChannelOutboundBuffer.fireChannelWritabilityChanged(ChannelOutboundBuffer.java:599) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.ChannelOutboundBuffer.setWritable(ChannelOutboundBuffer.java:565) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.ChannelOutboundBuffer.decrementPendingOutboundBytes(ChannelOutboundBuffer.java:208) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.ChannelOutboundBuffer.remove(ChannelOutboundBuffer.java:273) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.ChannelOutboundBuffer.removeBytes(ChannelOutboundBuffer.java:352) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.socket.nio.NioSocketChannel.doWrite(NioSocketChannel.java:442) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannel$AbstractUnsafe.flush0(AbstractChannel.java:856) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.forceFlush(AbstractNioChannel.java:368) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:574) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:488) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:450) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:873) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at java.lang.Thread.run(Thread.java:745) [?:1.8.0_102]
2016-11-04 18:00:29,649 [WorkerThread-5] Http2HttpBridgeHandler ERROR: state=State{stream=0, queue=[State{stream=33, queue=[State{stream=39, queue=[State{stream=41, queue=[State{stream=43, queue=[State{stream=45, queue=[State{stream=49, queue=[State{stream=51, queue=[State{stream=53, queue=[State{stream=55, queue=[State{stream=57, queue=[State{stream=59, queue=[State{stream=61, queue=[State{stream=65, queue=[State{stream=67, queue=[State{stream=69, queue=[State{stream=71, queue=[State{stream=73, queue=[State{stream=75, queue=[State{stream=77, queue=[State{stream=79, queue=[], streamableBytes=27622, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=24415, pseudoTime=0, totalQueuedWeights=0, active=true}], streamableBytes=16376, activeCountForTree=2, priorityQueueIndex=0, pseudoTimeToWrite=40801, pseudoTime=24415, totalQueuedWeights=220, active=true}], streamableBytes=52037, activeCountForTree=3, priorityQueueIndex=0, pseudoTimeToWrite=40801, pseudoTime=40801, totalQueuedWeights=220, active=true}], streamableBytes=52027, activeCountForTree=4, priorityQueueIndex=0, pseudoTimeToWrite=40811, pseudoTime=40801, totalQueuedWeights=220, active=true}], streamableBytes=52037, activeCountForTree=5, priorityQueueIndex=0, pseudoTimeToWrite=40811, pseudoTime=40811, totalQueuedWeights=220, active=true}], streamableBytes=27622, activeCountForTree=6, priorityQueueIndex=0, pseudoTimeToWrite=65226, pseudoTime=40811, totalQueuedWeights=220, active=true}], streamableBytes=51011, activeCountForTree=7, priorityQueueIndex=0, pseudoTimeToWrite=66252, pseudoTime=65226, totalQueuedWeights=220, active=true}], streamableBytes=16376, activeCountForTree=8, priorityQueueIndex=0, pseudoTimeToWrite=142704, pseudoTime=66252, totalQueuedWeights=220, active=true}], streamableBytes=52027, activeCountForTree=9, priorityQueueIndex=0, pseudoTimeToWrite=142714, pseudoTime=142704, totalQueuedWeights=220, active=true}], streamableBytes=51011, activeCountForTree=10, priorityQueueIndex=0, pseudoTimeToWrite=143740, pseudoTime=142714, totalQueuedWeights=220, active=true}], streamableBytes=52027, activeCountForTree=11, priorityQueueIndex=0, pseudoTimeToWrite=143750, pseudoTime=143740, totalQueuedWeights=220, active=true}], streamableBytes=27622, activeCountForTree=12, priorityQueueIndex=0, pseudoTimeToWrite=168165, pseudoTime=143750, totalQueuedWeights=220, active=true}], streamableBytes=52027, activeCountForTree=13, priorityQueueIndex=0, pseudoTimeToWrite=168175, pseudoTime=168165, totalQueuedWeights=220, active=true}], streamableBytes=27622, activeCountForTree=14, priorityQueueIndex=0, pseudoTimeToWrite=192590, pseudoTime=168175, totalQueuedWeights=220, active=true}], streamableBytes=16376, activeCountForTree=15, priorityQueueIndex=0, pseudoTimeToWrite=269042, pseudoTime=192590, totalQueuedWeights=220, active=true}], streamableBytes=52037, activeCountForTree=16, priorityQueueIndex=0, pseudoTimeToWrite=269042, pseudoTime=269042, totalQueuedWeights=220, active=true}], streamableBytes=51011, activeCountForTree=17, priorityQueueIndex=0, pseudoTimeToWrite=270068, pseudoTime=269042, totalQueuedWeights=220, active=true}], streamableBytes=52027, activeCountForTree=18, priorityQueueIndex=0, pseudoTimeToWrite=270078, pseudoTime=270068, totalQueuedWeights=220, active=true}], streamableBytes=27622, activeCountForTree=19, priorityQueueIndex=0, pseudoTimeToWrite=370945, pseudoTime=270078, totalQueuedWeights=220, active=true}], streamableBytes=0, activeCountForTree=19, priorityQueueIndex=0, pseudoTimeToWrite=1156657, pseudoTime=398567, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=19, priorityQueueIndex=-1, pseudoTimeToWrite=0, pseudoTime=1156657, totalQueuedWeights=220, active=false}
2016-11-04 18:00:29,650 [WorkerThread-5] ExceptionHandler ERROR: name=Http2ExceptionHandler, channel=[id: 0x5e6e957c, L:/aaa.aaa.aaa.aaa:443 - R:/bbb.bbb.bbb.bbb:55169]
 java.lang.IllegalArgumentException: e.priorityQueueIndex(): 0 (expected: -1)
    at io.netty.util.internal.PriorityQueue.offer(PriorityQueue.java:83) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.util.internal.PriorityQueue.offer(PriorityQueue.java:32) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.handler.codec.http2.WeightedFairQueueByteDistributor$State.offer(WeightedFairQueueByteDistributor.java:299) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.handler.codec.http2.WeightedFairQueueByteDistributor.distributeToChildren(WeightedFairQueueByteDistributor.java:198) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.handler.codec.http2.WeightedFairQueueByteDistributor.distribute(WeightedFairQueueByteDistributor.java:130) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.handler.codec.http2.DefaultHttp2RemoteFlowController$WritabilityMonitor.writePendingBytes(DefaultHttp2RemoteFlowController.java:631) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.handler.codec.http2.DefaultHttp2RemoteFlowController.writePendingBytes(DefaultHttp2RemoteFlowController.java:255) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.handler.codec.http2.Http2ConnectionHandler.flush(Http2ConnectionHandler.java:161) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at com.squarespace.echo.http2.streams.Http2HttpBridgeHandler.flush(Http2HttpBridgeHandler.java:43) ~[echo-http-2.17.30.jar:?]
    at io.netty.handler.codec.http2.Http2ConnectionHandler.channelWritabilityChanged(Http2ConnectionHandler.java:385) ~[netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:445) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:427) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelWritabilityChanged(AbstractChannelHandlerContext.java:420) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.ChannelInboundHandlerAdapter.channelWritabilityChanged(ChannelInboundHandlerAdapter.java:119) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:445) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:427) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelWritabilityChanged(AbstractChannelHandlerContext.java:420) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.ChannelInboundHandlerAdapter.channelWritabilityChanged(ChannelInboundHandlerAdapter.java:119) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:445) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:427) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelWritabilityChanged(AbstractChannelHandlerContext.java:420) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.ChannelInboundHandlerAdapter.channelWritabilityChanged(ChannelInboundHandlerAdapter.java:119) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:445) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:427) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelWritabilityChanged(AbstractChannelHandlerContext.java:420) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelWritabilityChanged(DefaultChannelPipeline.java:1357) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:445) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelWritabilityChanged(AbstractChannelHandlerContext.java:427) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.DefaultChannelPipeline.fireChannelWritabilityChanged(DefaultChannelPipeline.java:938) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.ChannelOutboundBuffer$2.run(ChannelOutboundBuffer.java:593) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:418) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:454) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:873) [netty-all-4.1.7.Final-SNAPSHOT.jar:4.1.7.Final-SNAPSHOT]
    at java.lang.Thread.run(Thread.java:745) [?:1.8.0_102]
public class Http2HttpBridgeHandler extends Http2ConnectionHandler {

  @Override
  public void flush(ChannelHandlerContext ctx) throws Http2Exception {


    try {
      super.flush(ctx);
    } catch (Throwable t) {

      if (LOG.isErrorEnabled()) {

        Http2ConnectionEncoder encoder = encoder();
        String value = toString(encoder);

        LOG.error("state={}", value);
      }

      throw t;
    }
  }

  private static String toString(Http2ConnectionEncoder encoder) {

    DefaultHttp2RemoteFlowController flow = (DefaultHttp2RemoteFlowController)encoder.flowController();
    WeightedFairQueueByteDistributor distributor = streamByteDistributor(flow);
    Object connectionState = connectionState(distributor);

    return toString(connectionState);
  }

  private static String toString(Object state) {

    ToStringHelper helper = MoreObjects.toStringHelper(state);

    try {

      Class<?> clazz = state.getClass();

      Field[] fields = clazz.getDeclaredFields();

      for (Field field : fields) {
        field.setAccessible(true);

        String name = field.getName();
        Object value = field.get(state);

        if (name.equals("stream")) {
          helper.add(name, ((Http2Stream)value).id());

        } else if (name.equals("queue")) {

          List<Object> dst = new ArrayList<>();

          for (Object element : (Queue<?>)value) {
            dst.add(toString(element));
          }

          helper.add(name, dst);

        } else if (!name.contains("$")) {
          helper.add(name, value);
        }
      }

    } catch (Exception err) {
      LOG.error("Exception: {}", state, err);
    }

    return helper.toString();
  }

  private static WeightedFairQueueByteDistributor streamByteDistributor(DefaultHttp2RemoteFlowController flow) {
    return (WeightedFairQueueByteDistributor)value(flow, "streamByteDistributor");
  }

  private static Object connectionState(WeightedFairQueueByteDistributor distributor) {
    return value(distributor, "connectionState");
  }

  private static Object value(Object dst, String name) {
    if (dst != null) {
      try {
        Class<?> clazz = dst.getClass();
        Field field = clazz.getDeclaredField(name);
        field.setAccessible(true);
        return field.get(dst);
      } catch (Exception err) {
        LOG.error("Exception: obj={}, name={}", dst, name, err);
      }
    }

    return null;
  }
}

@rkapsi
Copy link
Member Author

rkapsi commented Nov 4, 2016

@Scottmitch great. That's exactly what I toString'd.

Look for the two codeblocks right before the stacktraces. They're rendered as a single line. Copy & Paste them into some Text Editor.

@Scottmitch
Copy link
Member

Scottmitch commented Nov 4, 2016

@rkapsi - can you show me the state before too (I realize this will impact performance, only do this if you are OK with this in your environment)

@Override
  public void flush(ChannelHandlerContext ctx) throws Http2Exception {


  String beforeState = null;
  if (LOG.isErrorEnabled()) {
    Http2ConnectionEncoder encoder = encoder();
    beforeState = toString(encoder);
  }
    try {
      super.flush(ctx);
    } catch (Throwable t) {

      if (LOG.isErrorEnabled()) {

        Http2ConnectionEncoder encoder = encoder();
        String value = toString(encoder);

        LOG.error("before state={}", beforeState);
        LOG.error("after state={}", value);
      }

      throw t;
    }
  }

@rkapsi
Copy link
Member Author

rkapsi commented Nov 4, 2016

016-11-04 19:00:56,334 [WorkerThread-0] Http2HttpBridgeHandler ERROR: 

before=State{stream=0, queue=[State{stream=3, queue=[State{stream=11, queue=[State{stream=13, queue=[State{stream=17, queue=[State{stream=19, queue=[State{stream=23, queue=[State{stream=25, queue=[State{stream=27, queue=[State{stream=29, queue=[], streamableBytes=96568, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=32010, pseudoTime=16005, totalQueuedWeights=0, active=true}], streamableBytes=1669, activeCountForTree=2, priorityQueueIndex=0, pseudoTimeToWrite=32010, pseudoTime=32010, totalQueuedWeights=220, active=true}], streamableBytes=104854, activeCountForTree=3, priorityQueueIndex=0, pseudoTimeToWrite=32010, pseudoTime=32010, totalQueuedWeights=220, active=true}], streamableBytes=36936, activeCountForTree=4, priorityQueueIndex=0, pseudoTimeToWrite=146597, pseudoTime=32010, totalQueuedWeights=220, active=true}], streamableBytes=56007, activeCountForTree=5, priorityQueueIndex=0, pseudoTimeToWrite=146597, pseudoTime=146597, totalQueuedWeights=220, active=true}], streamableBytes=98185, activeCountForTree=6, priorityQueueIndex=0, pseudoTimeToWrite=179084, pseudoTime=146597, totalQueuedWeights=220, active=true}], streamableBytes=27101, activeCountForTree=7, priorityQueueIndex=0, pseudoTimeToWrite=179084, pseudoTime=179084, totalQueuedWeights=220, active=true}], streamableBytes=0, activeCountForTree=7, priorityQueueIndex=0, pseudoTimeToWrite=481469, pseudoTime=179084, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=7, priorityQueueIndex=0, pseudoTimeToWrite=657600, pseudoTime=528718, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=7, priorityQueueIndex=-1, pseudoTimeToWrite=0, pseudoTime=657600, totalQueuedWeights=220, active=false}, 

after=State{stream=0, queue=[State{stream=3, queue=[State{stream=11, queue=[State{stream=17, queue=[State{stream=19, queue=[State{stream=23, queue=[State{stream=25, queue=[State{stream=27, queue=[State{stream=29, queue=[], streamableBytes=96568, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=32010, pseudoTime=16005, totalQueuedWeights=0, active=true}], streamableBytes=1669, activeCountForTree=2, priorityQueueIndex=0, pseudoTimeToWrite=32010, pseudoTime=32010, totalQueuedWeights=220, active=true}], streamableBytes=104854, activeCountForTree=3, priorityQueueIndex=0, pseudoTimeToWrite=32010, pseudoTime=32010, totalQueuedWeights=220, active=true}], streamableBytes=36936, activeCountForTree=4, priorityQueueIndex=0, pseudoTimeToWrite=146597, pseudoTime=32010, totalQueuedWeights=220, active=true}], streamableBytes=56007, activeCountForTree=5, priorityQueueIndex=0, pseudoTimeToWrite=146597, pseudoTime=146597, totalQueuedWeights=220, active=true}], streamableBytes=98185, activeCountForTree=6, priorityQueueIndex=0, pseudoTimeToWrite=179084, pseudoTime=146597, totalQueuedWeights=220, active=true}], streamableBytes=0, activeCountForTree=6, priorityQueueIndex=0, pseudoTimeToWrite=555819, pseudoTime=206185, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=6, priorityQueueIndex=0, pseudoTimeToWrite=657600, pseudoTime=555819, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=6, priorityQueueIndex=-1, pseudoTimeToWrite=0, pseudoTime=657600, totalQueuedWeights=220, active=false}
2016-11-04 19:05:36,067 [WorkerThread-6] Http2HttpBridgeHandler ERROR: 
before=State{stream=0, queue=[State{stream=1, queue=[State{stream=3, queue=[State{stream=5, queue=[State{stream=7, queue=[State{stream=13, queue=[State{stream=15, queue=[State{stream=19, queue=[State{stream=23, queue=[], streamableBytes=113, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=339, pseudoTime=339, totalQueuedWeights=0, active=true}], streamableBytes=0, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=565, pseudoTime=452, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=452, pseudoTime=565, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=678, pseudoTime=452, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=791, pseudoTime=678, totalQueuedWeights=220, active=false}], streamableBytes=113, activeCountForTree=2, priorityQueueIndex=0, pseudoTimeToWrite=791, pseudoTime=791, totalQueuedWeights=220, active=true}], streamableBytes=0, activeCountForTree=2, priorityQueueIndex=0, pseudoTimeToWrite=791, pseudoTime=791, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=2, priorityQueueIndex=0, pseudoTimeToWrite=791, pseudoTime=791, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=2, priorityQueueIndex=-1, pseudoTimeToWrite=0, pseudoTime=791, totalQueuedWeights=220, active=false}, 

after=State{stream=0, queue=[State{stream=1, queue=[State{stream=3, queue=[State{stream=7, queue=[State{stream=13, queue=[State{stream=15, queue=[State{stream=19, queue=[State{stream=23, queue=[], streamableBytes=113, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=339, pseudoTime=339, totalQueuedWeights=0, active=true}], streamableBytes=0, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=565, pseudoTime=452, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=452, pseudoTime=565, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=678, pseudoTime=452, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=791, pseudoTime=678, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=904, pseudoTime=904, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=791, pseudoTime=904, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=1, priorityQueueIndex=-1, pseudoTimeToWrite=0, pseudoTime=791, totalQueuedWeights=220, active=false}

@rkapsi
Copy link
Member Author

rkapsi commented Nov 4, 2016

The first before/after "nicely" formatted:

before=State{stream=0, 
 queue=[State{stream=3, 
  queue=[State{stream=11, 
   queue=[State{stream=13, 
    queue=[State{stream=17, 
     queue=[State{stream=19, 
      queue=[State{stream=23, 
       queue=[State{stream=25, 
        queue=[State{stream=27, 
         queue=[State{stream=29, 
          queue=[], 
          streamableBytes=96568, 
          activeCountForTree=1, 
          priorityQueueIndex=0, 
          pseudoTimeToWrite=32010, 
          pseudoTime=16005, 
          totalQueuedWeights=0, 
          active=true}], 
         streamableBytes=1669, 
         activeCountForTree=2, 
         priorityQueueIndex=0, 
         pseudoTimeToWrite=32010, 
         pseudoTime=32010, 
         totalQueuedWeights=220, 
         active=true}], 
        streamableBytes=104854, 
        activeCountForTree=3, 
        priorityQueueIndex=0, 
        pseudoTimeToWrite=32010, 
        pseudoTime=32010, 
        totalQueuedWeights=220, 
        active=true}], 
       streamableBytes=36936, 
       activeCountForTree=4, 
       priorityQueueIndex=0, 
       pseudoTimeToWrite=146597, 
       pseudoTime=32010, 
       totalQueuedWeights=220, 
       active=true}], 
      streamableBytes=56007, 
      activeCountForTree=5, 
      priorityQueueIndex=0,
      pseudoTimeToWrite=146597, 
      pseudoTime=146597, 
      totalQueuedWeights=220, 
      active=true}], 
     streamableBytes=98185, 
     activeCountForTree=6, 
     priorityQueueIndex=0, 
     pseudoTimeToWrite=179084, 
     pseudoTime=146597, 
     totalQueuedWeights=220, 
     active=true}], 
    streamableBytes=27101, 
    activeCountForTree=7, 
    priorityQueueIndex=0, 
    pseudoTimeToWrite=179084, 
    pseudoTime=179084, 
    totalQueuedWeights=220, 
    active=true}], 
   streamableBytes=0, 
   activeCountForTree=7, 
   priorityQueueIndex=0, 
   pseudoTimeToWrite=481469, 
   pseudoTime=179084, 
   totalQueuedWeights=220, 
   active=false}], 
  streamableBytes=0, 
  activeCountForTree=7, 
  priorityQueueIndex=0, 
  pseudoTimeToWrite=657600, 
  pseudoTime=528718, 
  totalQueuedWeights=220, 
  active=false}], 
 streamableBytes=0, 
 activeCountForTree=7, 
 priorityQueueIndex=-1, 
 pseudoTimeToWrite=0, 
 pseudoTime=657600, t
 otalQueuedWeights=220, 
 active=false}, 

after=State{stream=0, 
 queue=[State{stream=3, 
  queue=[State{stream=11, 
   queue=[State{stream=17, 
    queue=[State{stream=19, 
     queue=[State{stream=23, 
      queue=[State{stream=25, 
       queue=[State{stream=27, 
        queue=[State{stream=29, 
         queue=[], 
         streamableBytes=96568, 
         activeCountForTree=1, 
         priorityQueueIndex=0, 
         pseudoTimeToWrite=32010, 
         pseudoTime=16005, 
         totalQueuedWeights=0, 
         active=true}], 
        streamableBytes=1669, 
        activeCountForTree=2, 
        priorityQueueIndex=0, 
        pseudoTimeToWrite=32010, 
        pseudoTime=32010, 
        totalQueuedWeights=220, 
        active=true}], 
       streamableBytes=104854, 
       activeCountForTree=3, 
       priorityQueueIndex=0, 
       pseudoTimeToWrite=32010, 
       pseudoTime=32010, 
       totalQueuedWeights=220, 
       active=true}], 
      streamableBytes=36936, 
      activeCountForTree=4, 
      priorityQueueIndex=0, 
      pseudoTimeToWrite=146597, 
      pseudoTime=32010, 
      totalQueuedWeights=220, 
      active=true}], 
     streamableBytes=56007, 
     activeCountForTree=5, 
     priorityQueueIndex=0, 
     pseudoTimeToWrite=146597, 
     pseudoTime=146597, 
     totalQueuedWeights=220, 
     active=true}], 
    streamableBytes=98185, 
    activeCountForTree=6, 
    priorityQueueIndex=0, 
    pseudoTimeToWrite=179084, 
    pseudoTime=146597, 
    totalQueuedWeights=220, 
    active=true}], 
   streamableBytes=0, 
   activeCountForTree=6, 
   priorityQueueIndex=0, 
   pseudoTimeToWrite=555819, 
   pseudoTime=206185, 
   totalQueuedWeights=220, 
   active=false}], 
  streamableBytes=0, 
  activeCountForTree=6, 
  priorityQueueIndex=0, 
  pseudoTimeToWrite=657600, 
  pseudoTime=555819, 
  totalQueuedWeights=220, 
  active=false}], 
 streamableBytes=0, 
 activeCountForTree=6, 
 priorityQueueIndex=-1, 
 pseudoTimeToWrite=0, 
 pseudoTime=657600, 
 totalQueuedWeights=220, 
 active=false}

@Scottmitch
Copy link
Member

Scottmitch commented Nov 4, 2016

@rkapsi - thanks! can you also tell me the maxBytes value for the initial call to WeightedFairQueueByteDistributor#distribute(int, Writer)? It is derived from DefaultHttp2RemoteFlowController#writableBytes().

@rkapsi
Copy link
Member Author

rkapsi commented Nov 4, 2016

@Scottmitch initial call as in the very first call or the value for before/after the exception is being thrown?

@Scottmitch
Copy link
Member

Scottmitch commented Nov 4, 2016

@rkapsi - Just the value of the argument which triggers the call to WeightedFairQueueByteDistributor#distribute(int /*this value*/, Writer) when the exception occurs (shouldn't change before and after).

@Scottmitch
Copy link
Member

@rkapsi - also are you using the default value for WeightedFairQueueByteDistributor#allocationQuantum, and if not can you tell me what value you use?

@rkapsi
Copy link
Member Author

rkapsi commented Nov 4, 2016

before=state{writableBytes=43398, connectionState=State{stream=0, queue=[State{stream=25, queue=[State{stream=27, queue=[State{stream=29, queue=[State{stream=33, queue=[State{stream=35, queue=[State{stream=37, queue=[State{stream=41, queue=[State{stream=43, queue=[State{stream=45, queue=[State{stream=49, queue=[State{stream=51, queue=[State{stream=53, queue=[State{stream=57, queue=[State{stream=59, queue=[State{stream=63, queue=[State{stream=71, queue=[], streamableBytes=13674, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=68440, pseudoTime=27378, totalQueuedWeights=0, active=true}], streamableBytes=10, activeCountForTree=2, priorityQueueIndex=0, pseudoTimeToWrite=82124, pseudoTime=68440, totalQueuedWeights=220, active=true}], streamableBytes=13674, activeCountForTree=3, priorityQueueIndex=0, pseudoTimeToWrite=82134, pseudoTime=82124, totalQueuedWeights=220, active=true}], streamableBytes=13674, activeCountForTree=4, priorityQueueIndex=0, pseudoTimeToWrite=95828, pseudoTime=82134, totalQueuedWeights=220, active=true}], streamableBytes=13674, activeCountForTree=5, priorityQueueIndex=0, pseudoTimeToWrite=95838, pseudoTime=95828, totalQueuedWeights=220, active=true}], streamableBytes=13674, activeCountForTree=6, priorityQueueIndex=0, pseudoTimeToWrite=95848, pseudoTime=95838, totalQueuedWeights=220, active=true}], streamableBytes=13674, activeCountForTree=7, priorityQueueIndex=0, pseudoTimeToWrite=109542, pseudoTime=95848, totalQueuedWeights=220, active=true}], streamableBytes=0, activeCountForTree=7, priorityQueueIndex=0, pseudoTimeToWrite=109552, pseudoTime=109542, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=7, priorityQueueIndex=0, pseudoTimeToWrite=109562, pseudoTime=109552, totalQueuedWeights=220, active=false}], streamableBytes=13674, activeCountForTree=8, priorityQueueIndex=0, pseudoTimeToWrite=123256, pseudoTime=109562, totalQueuedWeights=220, active=true}], streamableBytes=0, activeCountForTree=8, priorityQueueIndex=0, pseudoTimeToWrite=123266, pseudoTime=123256, totalQueuedWeights=220, active=false}], streamableBytes=1042, activeCountForTree=9, priorityQueueIndex=0, pseudoTimeToWrite=135908, pseudoTime=123266, totalQueuedWeights=220, active=true}], streamableBytes=0, activeCountForTree=9, priorityQueueIndex=0, pseudoTimeToWrite=149602, pseudoTime=135908, totalQueuedWeights=220, active=false}], streamableBytes=13674, activeCountForTree=10, priorityQueueIndex=0, pseudoTimeToWrite=149612, pseudoTime=149602, totalQueuedWeights=220, active=true}], streamableBytes=1016, activeCountForTree=11, priorityQueueIndex=0, pseudoTimeToWrite=149622, pseudoTime=149612, totalQueuedWeights=220, active=true}], streamableBytes=6404, activeCountForTree=12, priorityQueueIndex=0, pseudoTimeToWrite=326792, pseudoTime=149622, totalQueuedWeights=220, active=true}], streamableBytes=0, activeCountForTree=12, priorityQueueIndex=-1, pseudoTimeToWrite=0, pseudoTime=340466, totalQueuedWeights=220, active=false}}, 
after=state{writableBytes=32768, connectionState=State{stream=0, queue=[State{stream=27, queue=[State{stream=33, queue=[State{stream=35, queue=[State{stream=37, queue=[State{stream=41, queue=[State{stream=43, queue=[State{stream=45, queue=[State{stream=49, queue=[State{stream=51, queue=[State{stream=53, queue=[State{stream=57, queue=[State{stream=59, queue=[State{stream=63, queue=[State{stream=71, queue=[], streamableBytes=13674, activeCountForTree=1, priorityQueueIndex=0, pseudoTimeToWrite=68440, pseudoTime=27378, totalQueuedWeights=0, active=true}], streamableBytes=10, activeCountForTree=2, priorityQueueIndex=0, pseudoTimeToWrite=82124, pseudoTime=68440, totalQueuedWeights=220, active=true}], streamableBytes=13674, activeCountForTree=3, priorityQueueIndex=0, pseudoTimeToWrite=82134, pseudoTime=82124, totalQueuedWeights=220, active=true}], streamableBytes=13674, activeCountForTree=4, priorityQueueIndex=0, pseudoTimeToWrite=95828, pseudoTime=82134, totalQueuedWeights=220, active=true}], streamableBytes=13674, activeCountForTree=5, priorityQueueIndex=0, pseudoTimeToWrite=95838, pseudoTime=95828, totalQueuedWeights=220, active=true}], streamableBytes=13674, activeCountForTree=6, priorityQueueIndex=0, pseudoTimeToWrite=95848, pseudoTime=95838, totalQueuedWeights=220, active=true}], streamableBytes=13674, activeCountForTree=7, priorityQueueIndex=0, pseudoTimeToWrite=109542, pseudoTime=95848, totalQueuedWeights=220, active=true}], streamableBytes=0, activeCountForTree=7, priorityQueueIndex=0, pseudoTimeToWrite=109552, pseudoTime=109542, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=7, priorityQueueIndex=0, pseudoTimeToWrite=109562, pseudoTime=109552, totalQueuedWeights=220, active=false}], streamableBytes=13674, activeCountForTree=8, priorityQueueIndex=0, pseudoTimeToWrite=123256, pseudoTime=109562, totalQueuedWeights=220, active=true}], streamableBytes=0, activeCountForTree=8, priorityQueueIndex=0, pseudoTimeToWrite=123266, pseudoTime=123256, totalQueuedWeights=220, active=false}], streamableBytes=1042, activeCountForTree=9, priorityQueueIndex=0, pseudoTimeToWrite=135908, pseudoTime=123266, totalQueuedWeights=220, active=true}], streamableBytes=0, activeCountForTree=9, priorityQueueIndex=0, pseudoTimeToWrite=149612, pseudoTime=135908, totalQueuedWeights=220, active=false}], streamableBytes=0, activeCountForTree=9, priorityQueueIndex=0, pseudoTimeToWrite=361560, pseudoTime=163286, totalQueuedWeights=220, active=false}], 

@rkapsi
Copy link
Member Author

rkapsi commented Nov 4, 2016

@Scottmitch I'm using the default value. The only non-default value I'm using is maxConcurrentStreams which is set to 1.

@Scottmitch
Copy link
Member

@rkapsi - I hacked together a unit test with one of your earlier state dumps and couldn't repo (I'm missing something), but I will try again now that you have provided the writableBytes and maybe it will become more clear...

@rkapsi
Copy link
Member Author

rkapsi commented Nov 4, 2016

@Scottmitch would it help if... You change the PriorityQueue#offer()'s exception to include the System#indentityHashCode() of the offending argument and I'll output the identity hashcode in the before/after dumps?!

@Scottmitch
Copy link
Member

Scottmitch commented Nov 4, 2016

It looks like the structure of the queues/tree has changed before and after ... this is a bit surprising. I would expect at least 1 element to be missing (bcz of this exception), and the queues/tree structure to have a hole ... but it looks like you are still able to traverse from the root to the leaf. For example how does 27 get in 0's queue? Only direct children should be in the queue, and I don't see how a re-prioritization can occur during "byte distribution".

Also it looks like only the state for streams 25, 27, 29, and 33 change during this allocation, so we may be able to reduce the test case to just these streams

would it help if...

Yes it may help to know when the exception is being thrown.

@Scottmitch
Copy link
Member

Scottmitch commented Nov 4, 2016

I don't see how a re-prioritization can occur

Its starting to come back to me now ... if the data frame has the EOS flag set, and the write completes synchronously, then we may close the stream, generate a priority event, notify the stream listeners via onPriorityTreeParentChanging, and WeightedFairQueueByteDistributor will remove from the parent queue ... so it may makes sense that the queues are missing streams after and the links are still valid

@Scottmitch Scottmitch added this to the 4.1.7.Final milestone Nov 5, 2016
@Scottmitch
Copy link
Member

@rkapsi - I was able to reproduce the issue locally ... stand by for a PR.

@Scottmitch
Copy link
Member

See #6004

Scottmitch added a commit to Scottmitch/netty that referenced this issue Nov 12, 2016
Motivation:
If a stream is not able to send any data (flow control window for the stream is exhausted) but has descendants who can send data then WeightedFairQueueByteDistributor may incorrectly modify the pseudo time and also double add the associated state to the parent's priority queue. The pseudo time should only be modified if a node is moved in the priority tree, and not if there happens to be no active streams in its descendent tree and a descendent is moved (e.g. removed from the tree because it wrote all data and the last data frame was EOS). Also the state objects for WeightedFairQueueByteDistributor should only appear once in any queue. If this condition is violated the pseudo time accounting would be biased at and assumptions in WeightedFairQueueByteDistributor would be invalidated.

Modifications:
- WeightedFairQueueByteDistributor#isActiveCountChangeForTree should not allow re-adding to the priority queue if we are currently processing a node in the distribution algorithm. The distribution algorithm will re-evaluate if the node should be re-added on the tail end of the recursion.

Result:
Fixes netty#5980
liuzhengyang pushed a commit to liuzhengyang/netty that referenced this issue Sep 10, 2017
Motivation:
If a stream is not able to send any data (flow control window for the stream is exhausted) but has descendants who can send data then WeightedFairQueueByteDistributor may incorrectly modify the pseudo time and also double add the associated state to the parent's priority queue. The pseudo time should only be modified if a node is moved in the priority tree, and not if there happens to be no active streams in its descendent tree and a descendent is moved (e.g. removed from the tree because it wrote all data and the last data frame was EOS). Also the state objects for WeightedFairQueueByteDistributor should only appear once in any queue. If this condition is violated the pseudo time accounting would be biased at and assumptions in WeightedFairQueueByteDistributor would be invalidated.

Modifications:
- WeightedFairQueueByteDistributor#isActiveCountChangeForTree should not allow re-adding to the priority queue if we are currently processing a node in the distribution algorithm. The distribution algorithm will re-evaluate if the node should be re-added on the tail end of the recursion.

Result:
Fixes netty#5980
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants