Re: Tomcat 9.0.8 asynchronous websocket issue

2019-03-01 Thread Austin Bookhart
On Fri, Mar 1, 2019 at 4:46 AM Mark Thomas  wrote:
>
> On 28/02/2019 20:29, Austin Bookhart wrote:
> > Hi,
> >
> > I have a question regarding an asynchronous websocket implementation
> > we have in our application. We have run into issues where on a rare
> > occasion the websocket endpoint will become unusable due to what seems
> > to be a thread holding onto resources and not releasing them. Below is
> > the main structure of our endpoint. Some parts have been removed or
> > commented out, but it gets the basic structure across.
> >
> > We call "sendMessageToUser" in order to send a message to a client's
> > browser. The issue that we have seen is if we breakpoint at the line
> > that waits for the future to resolve, "future.get()", and reload the
> > current client's browser, the endpoint becomes unusable where no
> > messages can be sent or received any longer. Only a restart resolves
> > the issue. We wanted to find out if our implementation of the
> > asynchronous remote and future setup is correct or if there is a more
> > appropriate use of the API?
>
> There have been some bugs fixed in this area. I'd suggest testing with
> the latest 9.0.x release.
>
> Mark
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>

Thank you for the help. We upgraded to the latest version and don't
see the issues any longer. We'll have to do some more extensive
testing, but it looks good so far.

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



Re: tomcat 8.5.23 can not modify maxconcurrentstream setting

2019-03-01 Thread Helena Carbajo
> From what I see in the test a STREAM_REFUSED is returned when a the
maxConcurrentStream  is set to one. Yet I'd like to understand how this
value is changed internally. I think >the only difference with my code is
the call to the method doHttpUpgrade() which seems to send a GET for
upgrade. Does this perform the actual upgrade of the settings? If this >is
the case where is it implemented?



>Http2UpgradeHandler (which represents an HTTP/2 connection) sets the
maximum concurrent stream value when the connection is created:



>https://github.com/apache/tomcat/blob/master/java/org/apache/coyote/http2/Http2UpgradeHandler.java#L156




>This means if the value set on the protocol is changed dynamically, the
new value takes effect for all subsequent connections.



>The setting is communicated to the client as part of the connection
preface.



>https://github.com/apache/tomcat/blob/master/java/org/apache/coyote/http2/Http2UpgradeHandler.java#L229




>Well-behaved clients will respect this setting but Tomcat checks the limit
every time a new stream is created.



>https://github.com/apache/tomcat/blob/master/java/org/apache/coyote/http2/Http2UpgradeHandler.java#L1333




>You may find enabling Tomcat's debug logging for HTTP/2 instructive.



>Mark



Thanks. I finally understood how it all works.


Helena


El vie., 1 mar. 2019 a las 10:44, Mark Thomas () escribió:

> On 27/02/2019 08:37, Helena Carbajo wrote:
> >>> See
> >>>
> https://github.com/apache/tomcat/blob/8.5.x/test/org/apache/coyote/http2/TestHttp2Section_5_1.java#L174
> >
> > From what I see in the test a STREAM_REFUSED is returned when a the
> maxConcurrentStream  is set to one. Yet I'd like to understand how this
> value is changed internally. I think the only difference with my code is
> the call to the method doHttpUpgrade() which seems to send a GET for
> upgrade. Does this perform the actual upgrade of the settings? If this is
> the case where is it implemented?
>
> Http2UpgradeHandler (which represents an HTTP/2 connection) sets the
> maximum concurrent stream value when the connection is created:
>
>
> https://github.com/apache/tomcat/blob/master/java/org/apache/coyote/http2/Http2UpgradeHandler.java#L156
>
> This means if the value set on the protocol is changed dynamically, the
> new value takes effect for all subsequent connections.
>
> The setting is communicated to the client as part of the connection
> preface.
>
>
> https://github.com/apache/tomcat/blob/master/java/org/apache/coyote/http2/Http2UpgradeHandler.java#L229
>
> Well-behaved clients will respect this setting but Tomcat checks the
> limit every time a new stream is created.
>
>
> https://github.com/apache/tomcat/blob/master/java/org/apache/coyote/http2/Http2UpgradeHandler.java#L1333
>
> You may find enabling Tomcat's debug logging for HTTP/2 instructive.
>
> Mark
>
>
> >
> > -Original Message-
> > From: Mark Thomas 
> > Sent: martes, 26 de febrero de 2019 13:45
> > To: users@tomcat.apache.org
> > Subject: Re: tomcat 8.5.23 can not modify maxconcurrentstream setting
> >
> > See
> >
> https://github.com/apache/tomcat/blob/8.5.x/test/org/apache/coyote/http2/TestHttp2Section_5_1.java#L174
> >
> > Mark
> >
> >
> > On 26/02/2019 11:01, Helena Carbajo wrote:
> >> I'm trying to modify the value of MaxConcurrentStream for the tomcat
> server in order to check that it returns a STREAM_REFUSED when the client
> uses more streams, but I don't manage to change the default unlimited value.
> >>
> >> I've been inspecting the tomcat server code with a debugger and I saw
> it enters the method protected synchronized void set(Setting setting, Long
> value)  from the org.apache.coyote.http2.ConnectionSettingsLocal.java class
> to change the value for maxConcurrentStream. Yet, if I'm not wrong, it only
> modifies the pending hashSet not the current one, which is the one that is
> checked later on to determine if it is lower than the clients' active
> streams and therefore send the  STREAM_REFUSED code.
> >>
> >>
> >>
> >> I'm not sure if  I'm not modifying the value correctly. I use the
> Http2Protocol's method setMaxConcurrentStreams to set the value and then
> add the Http2Protocol to the connector(addUpgradeProtocol).
> >>
> >>
> >>
> >> I'd be grateful if someone could give me a hint of what is going on or
> what I'm doing wrong. Thank you!
> >>
> >>
> >
> >
> > -
> > To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> > For additional commands, e-mail: users-h...@tomcat.apache.org
> >
> >
> > -
> > To unsubscribe, e-mail: 

Re: Tomcat 9.0.8 asynchronous websocket issue

2019-03-01 Thread Mark Thomas
On 28/02/2019 20:29, Austin Bookhart wrote:
> Hi,
> 
> I have a question regarding an asynchronous websocket implementation
> we have in our application. We have run into issues where on a rare
> occasion the websocket endpoint will become unusable due to what seems
> to be a thread holding onto resources and not releasing them. Below is
> the main structure of our endpoint. Some parts have been removed or
> commented out, but it gets the basic structure across.
> 
> We call "sendMessageToUser" in order to send a message to a client's
> browser. The issue that we have seen is if we breakpoint at the line
> that waits for the future to resolve, "future.get()", and reload the
> current client's browser, the endpoint becomes unusable where no
> messages can be sent or received any longer. Only a restart resolves
> the issue. We wanted to find out if our implementation of the
> asynchronous remote and future setup is correct or if there is a more
> appropriate use of the API?

There have been some bugs fixed in this area. I'd suggest testing with
the latest 9.0.x release.

Mark

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



Re: tomcat 8.5.23 can not modify maxconcurrentstream setting

2019-03-01 Thread Mark Thomas
On 27/02/2019 08:37, Helena Carbajo wrote:
>>> See
>>> https://github.com/apache/tomcat/blob/8.5.x/test/org/apache/coyote/http2/TestHttp2Section_5_1.java#L174
> 
> From what I see in the test a STREAM_REFUSED is returned when a the 
> maxConcurrentStream  is set to one. Yet I'd like to understand how this value 
> is changed internally. I think the only difference with my code is the call 
> to the method doHttpUpgrade() which seems to send a GET for upgrade. Does 
> this perform the actual upgrade of the settings? If this is the case where is 
> it implemented?

Http2UpgradeHandler (which represents an HTTP/2 connection) sets the
maximum concurrent stream value when the connection is created:

https://github.com/apache/tomcat/blob/master/java/org/apache/coyote/http2/Http2UpgradeHandler.java#L156

This means if the value set on the protocol is changed dynamically, the
new value takes effect for all subsequent connections.

The setting is communicated to the client as part of the connection preface.

https://github.com/apache/tomcat/blob/master/java/org/apache/coyote/http2/Http2UpgradeHandler.java#L229

Well-behaved clients will respect this setting but Tomcat checks the
limit every time a new stream is created.

https://github.com/apache/tomcat/blob/master/java/org/apache/coyote/http2/Http2UpgradeHandler.java#L1333

You may find enabling Tomcat's debug logging for HTTP/2 instructive.

Mark


> 
> -Original Message-
> From: Mark Thomas  
> Sent: martes, 26 de febrero de 2019 13:45
> To: users@tomcat.apache.org
> Subject: Re: tomcat 8.5.23 can not modify maxconcurrentstream setting
> 
> See
> https://github.com/apache/tomcat/blob/8.5.x/test/org/apache/coyote/http2/TestHttp2Section_5_1.java#L174
> 
> Mark
> 
> 
> On 26/02/2019 11:01, Helena Carbajo wrote:
>> I'm trying to modify the value of MaxConcurrentStream for the tomcat server 
>> in order to check that it returns a STREAM_REFUSED when the client uses more 
>> streams, but I don't manage to change the default unlimited value.
>>
>> I've been inspecting the tomcat server code with a debugger and I saw it 
>> enters the method protected synchronized void set(Setting setting, Long 
>> value)  from the org.apache.coyote.http2.ConnectionSettingsLocal.java class 
>> to change the value for maxConcurrentStream. Yet, if I'm not wrong, it only 
>> modifies the pending hashSet not the current one, which is the one that is 
>> checked later on to determine if it is lower than the clients' active 
>> streams and therefore send the  STREAM_REFUSED code.
>>
>>
>>
>> I'm not sure if  I'm not modifying the value correctly. I use the 
>> Http2Protocol's method setMaxConcurrentStreams to set the value and then add 
>> the Http2Protocol to the connector(addUpgradeProtocol).
>>
>>
>>
>> I'd be grateful if someone could give me a hint of what is going on or what 
>> I'm doing wrong. Thank you!
>>
>>
> 
> 
> -
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
> 
> 
> -
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
> 


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



Re: Tomcat 9.0.8 asynchronous websocket issue

2019-03-01 Thread Johan Compagner
On Thu, 28 Feb 2019 at 21:29, Austin Bookhart <
austin.bookh...@hannonhill.com> wrote:

> Hi,
>
> I have a question regarding an asynchronous websocket implementation
> we have in our application. We have run into issues where on a rare
> occasion the websocket endpoint will become unusable due to what seems
> to be a thread holding onto resources and not releasing them. Below is
> the main structure of our endpoint. Some parts have been removed or
> commented out, but it gets the basic structure across.
>
> We call "sendMessageToUser" in order to send a message to a client's
> browser. The issue that we have seen is if we breakpoint at the line
> that waits for the future to resolve, "future.get()", and reload the
> current client's browser, the endpoint becomes unusable where no
>

The code below is very weird code to me, but i guess this is just to show
it?
Because if i look at the doc of the Async.sendText()
Then the get() of the Future should throw an exception on connections
errors.
But in your case it just never resolves?




> messages can be sent or received any longer. Only a restart resolves
> the issue. We wanted to find out if our implementation of the
> asynchronous remote and future setup is correct or if there is a more
> appropriate use of the API?
>
> Appreciate any help you can provide.
> Thanks,
> Austin
>
> @ServerEndpoint(value = "/websocket", configurator =
> GetHttpSessionConfigurator.class)
> public class WebSocketEndpoint
> {
> private static final Map clients =
> Collections.synchronizedMap(new HashMap());
> private static Future future = null;
>
> public static void sendMessageToUser(String username,
> WebSocketMessage message)
> {
> synchronized (clients)
> {
> clients.keySet().stream()
> .filter(client ->
> username.equals(clients.get(client).username))
> .forEach(client -> sendMessage(client, message));
> }
> }
>
> private static synchronized void sendMessage(Session client,
> WebSocketMessage message)
> {
> try
> {
> if (future == null)
> LOG.debug("Sending very first WebSocket message");
> else
> {
> // Before we send the next message, we have to wait
> for the previous message to complete
> LOG.debug("Waiting until last WebSocket message is being
> sent");
> future.get();
>
> LOG.debug("Last WebSocket message is not longer being
> sent. Sending a new message.");
> }
>
>
> // Send the message and store the Future for the next call
> future =
> client.getAsyncRemote().sendText(message.getJSONObject().toString());
> }
> catch (Exception e)
> {
> LOG.debug("An error occurred when sending a web socket
> message to client " + client, e);
> }
> }
>
> @OnOpen
> public void onOpen(Session client, EndpointConfig config)
> {
> //Construct SessionDetails information
> clients.put(client, new SessionDetails(..));
> }
>
> @OnClose
> public void onClose(Session client)
> {
> clients.remove(client);
> }
> }
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>
>

-- 
Johan Compagner
Servoy