You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Mark Thomas <ma...@apache.org> on 2018/08/01 19:47:11 UTC

Re: Upgrade with async leads to infinite onDataAvailable

On 25/07/18 10:25, Sergey Mashkov wrote:
> Hi
> 
> I am facing problem in the following scenario:
> 
> In response to an upgrade request I do upgrade, get WebConnection instance,
> take UpgradedServletInputStream from it
> As far it is a usual ServletInputStream I set ReadListener on it. It works
> almost properly so I didn't notice it for long. Now I see that unlike usual
> non-upgraded input stream, UpgradedServletInputStream does invoke
> onDataAvailable infinitely until I consume all arrived bytes. For example
> in the case if I simply ignore onDataAvailable invocation then the
> container will invoke it infinitely (does busy wait).
> 
> After reading source code I discovered that the difference between a
> regular CoyoteInputStream (with InputBuffer inside) and
> UpgradedServletInputStream is that they are processed by different
> Processor implementations.
> 
> When a selector fires OPEN_READ event it will pass it to
> AbstractProtocol.process that invokes processor (that invokes
> onDataAvailable through several layers). After that in both cases (regular
> and upgraded) AbstractProtocol does invoke longPoll (see if/elseif for LONG
> and UPGRADED, lines ~ 820 - 850) that looks like this:
> 
> protected void longPoll(SocketWrapperBase<?> socket, Processor processor) {
>     if (!processor.isAsync()) {
>         socket.registerReadInterest();
>     }
> }
> 
> Here is the difference: in case of regular non-upgraded request in async
> mode processor will return isAsync() = true because processor =
> Http11Processor. However upgraded requests are processed with processor =
> UpgradeProcessorExternal that will always return false and we setup read
> interest again.
> This is the reason we get onDataAvailable again and again as we always
> setup read interest.
> 
> The only workaround is to block inside onDataAvailable to wait until all
> received bytes will be processed however it is dangerous as it may lead to
> deadlock as we block inside of async processing loop.
> 
> Are there any suggestions what can be done to get it work properly?

I don't see this behaviour. I see onDataAvailable() being called only
after isReady() has returned false and once additional data has arrived.

I suggest you look at the test cases in
org.apache.coyote.http11.upgrade.TestUpgrade and produce the simplest
test case that reproduces the issue you are seeing along those lines.
You should have most of the code you need already in that class.

Once we have a test case the reproduces the issue, then we can take a
closer look.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org