Buildbot failure in on tomcat-9.0.x
Build status: BUILD FAILED: failed compile (failure) Worker used: bb_worker2_ubuntu URL: https://ci2.apache.org/#builders/37/builds/938 Blamelist: Mark Thomas Build Text: failed compile (failure) Status Detected: new failure Build Source Stamp: [branch 9.0.x] 0abb1b1a2b015ff963b5686d17322b1b08aae7cb Steps: worker_preparation: 0 git: 0 shell: 0 shell_1: 0 shell_2: 0 shell_3: 0 shell_4: 0 shell_5: 0 compile: 1 shell_6: 0 shell_7: 0 shell_8: 0 shell_9: 0 Rsync docs to nightlies.apache.org: 0 shell_10: 0 Rsync RAT to nightlies.apache.org: 0 compile_1: 2 shell_11: 0 Rsync Logs to nightlies.apache.org: 0 -- ASF Buildbot - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
(tomcat) branch 9.0.x updated: Improve handling of multiple disconnects
This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git The following commit(s) were added to refs/heads/9.0.x by this push: new 0abb1b1a2b Improve handling of multiple disconnects 0abb1b1a2b is described below commit 0abb1b1a2b015ff963b5686d17322b1b08aae7cb Author: Mark Thomas AuthorDate: Wed May 1 17:20:07 2024 +0100 Improve handling of multiple disconnects --- webapps/docs/changelog.xml | 4 webapps/examples/WEB-INF/classes/websocket/snake/Snake.java | 3 +-- .../WEB-INF/classes/websocket/snake/SnakeAnnotation.java | 9 + webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer.java | 5 ++--- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 85e4c780a1..7f523a580f 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -204,6 +204,10 @@ Examples: Increase the number of previous messages displayed when using the WebSocket chat application. (markt) + +Examples: Improve performance of WebSocket snake application when +multiple clients disconnect at the same time. (markt) + diff --git a/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java b/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java index 7a112220c5..3dea20da48 100644 --- a/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java +++ b/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java @@ -67,8 +67,7 @@ public class Snake { try { session.getBasicRemote().sendText(msg); } catch (IOException ioe) { -CloseReason cr = -new CloseReason(CloseCodes.CLOSED_ABNORMALLY, ioe.getMessage()); +CloseReason cr = new CloseReason(CloseCodes.CLOSED_ABNORMALLY, ioe.getMessage()); try { session.close(cr); } catch (IOException ioe2) { diff --git a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java index 84ed091b3f..48f92215f1 100644 --- a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java +++ b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java @@ -75,6 +75,9 @@ public class SnakeAnnotation { @OnOpen public void onOpen(Session session) { +// If the messages take longer than TICK_DELAY to be sent, the game isn't going to work properly. + session.getUserProperties().put("org.apache.tomcat.websocket.BLOCKING_SEND_TIMEOUT", +Long.valueOf(SnakeTimer.TICK_DELAY)); this.snake = new Snake(id, session); SnakeTimer.addSnake(snake); StringBuilder sb = new StringBuilder(); @@ -87,8 +90,7 @@ public class SnakeAnnotation { sb.append(','); } } -SnakeTimer.broadcast(String.format("{\"type\": \"join\",\"data\":[%s]}", -sb.toString())); +SnakeTimer.broadcast(String.format("{\"type\": \"join\",\"data\":[%s]}", sb.toString())); } @@ -109,8 +111,7 @@ public class SnakeAnnotation { @OnClose public void onClose() { SnakeTimer.removeSnake(snake); -SnakeTimer.broadcast(String.format("{\"type\": \"leave\", \"id\": %d}", -Integer.valueOf(id))); +SnakeTimer.broadcast(String.format("{\"type\": \"leave\", \"id\": %d}", Integer.valueOf(id))); } diff --git a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer.java b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer.java index 6b777e94e3..872f2dcddc 100644 --- a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer.java +++ b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer.java @@ -36,7 +36,7 @@ public class SnakeTimer { private static Timer gameTimer = null; -private static final long TICK_DELAY = 100; +static final long TICK_DELAY = 100; private static final ConcurrentHashMap snakes = new ConcurrentHashMap<>(); @@ -73,8 +73,7 @@ public class SnakeTimer { sb.append(','); } } -broadcast(String.format("{\"type\": \"update\", \"data\" : [%s]}", -sb.toString())); +broadcast(String.format("{\"type\": \"update\", \"data\" : [%s]}", sb.toString())); } protected static void broadcast(String message) { - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
(tomcat) branch 10.1.x updated: Improve handling of multiple disconnects
This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 10.1.x in repository https://gitbox.apache.org/repos/asf/tomcat.git The following commit(s) were added to refs/heads/10.1.x by this push: new 3cb29d58e2 Improve handling of multiple disconnects 3cb29d58e2 is described below commit 3cb29d58e25862208700dc3aa05d716c7c0d5f69 Author: Mark Thomas AuthorDate: Wed May 1 17:20:07 2024 +0100 Improve handling of multiple disconnects --- webapps/docs/changelog.xml | 4 webapps/examples/WEB-INF/classes/websocket/snake/Snake.java | 3 +-- .../WEB-INF/classes/websocket/snake/SnakeAnnotation.java | 9 + webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer.java | 5 ++--- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 3e6114bda0..ecd5c7e36b 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -195,6 +195,10 @@ Examples: Increase the number of previous messages displayed when using the WebSocket chat application. (markt) + +Examples: Improve performance of WebSocket snake application when +multiple clients disconnect at the same time. (markt) + diff --git a/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java b/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java index 619a879c80..5936bf4303 100644 --- a/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java +++ b/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java @@ -67,8 +67,7 @@ public class Snake { try { session.getBasicRemote().sendText(msg); } catch (IOException ioe) { -CloseReason cr = -new CloseReason(CloseCodes.CLOSED_ABNORMALLY, ioe.getMessage()); +CloseReason cr = new CloseReason(CloseCodes.CLOSED_ABNORMALLY, ioe.getMessage()); try { session.close(cr); } catch (IOException ioe2) { diff --git a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java index 37b1cf9626..442b5885ee 100644 --- a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java +++ b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java @@ -75,6 +75,9 @@ public class SnakeAnnotation { @OnOpen public void onOpen(Session session) { +// If the messages take longer than TICK_DELAY to be sent, the game isn't going to work properly. + session.getUserProperties().put("org.apache.tomcat.websocket.BLOCKING_SEND_TIMEOUT", +Long.valueOf(SnakeTimer.TICK_DELAY)); this.snake = new Snake(id, session); SnakeTimer.addSnake(snake); StringBuilder sb = new StringBuilder(); @@ -87,8 +90,7 @@ public class SnakeAnnotation { sb.append(','); } } -SnakeTimer.broadcast(String.format("{\"type\": \"join\",\"data\":[%s]}", -sb.toString())); +SnakeTimer.broadcast(String.format("{\"type\": \"join\",\"data\":[%s]}", sb.toString())); } @@ -109,8 +111,7 @@ public class SnakeAnnotation { @OnClose public void onClose() { SnakeTimer.removeSnake(snake); -SnakeTimer.broadcast(String.format("{\"type\": \"leave\", \"id\": %d}", -Integer.valueOf(id))); +SnakeTimer.broadcast(String.format("{\"type\": \"leave\", \"id\": %d}", Integer.valueOf(id))); } diff --git a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer.java b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer.java index 6b777e94e3..872f2dcddc 100644 --- a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer.java +++ b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer.java @@ -36,7 +36,7 @@ public class SnakeTimer { private static Timer gameTimer = null; -private static final long TICK_DELAY = 100; +static final long TICK_DELAY = 100; private static final ConcurrentHashMap snakes = new ConcurrentHashMap<>(); @@ -73,8 +73,7 @@ public class SnakeTimer { sb.append(','); } } -broadcast(String.format("{\"type\": \"update\", \"data\" : [%s]}", -sb.toString())); +broadcast(String.format("{\"type\": \"update\", \"data\" : [%s]}", sb.toString())); } protected static void broadcast(String message) { - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
(tomcat) branch main updated: Improve handling of multiple disconnects
This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git The following commit(s) were added to refs/heads/main by this push: new 3d077db9d7 Improve handling of multiple disconnects 3d077db9d7 is described below commit 3d077db9d744df1585d252d367166dd69b659c1e Author: Mark Thomas AuthorDate: Wed May 1 17:20:07 2024 +0100 Improve handling of multiple disconnects --- webapps/docs/changelog.xml | 4 webapps/examples/WEB-INF/classes/websocket/snake/Snake.java | 3 +-- .../WEB-INF/classes/websocket/snake/SnakeAnnotation.java | 9 + webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer.java | 5 ++--- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index e0ccec8de6..65b12d85c4 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -217,6 +217,10 @@ Examples: Increase the number of previous messages displayed when using the WebSocket chat application. (markt) + +Examples: Improve performance of WebSocket snake application when +multiple clients disconnect at the same time. (markt) + diff --git a/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java b/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java index 619a879c80..5936bf4303 100644 --- a/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java +++ b/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java @@ -67,8 +67,7 @@ public class Snake { try { session.getBasicRemote().sendText(msg); } catch (IOException ioe) { -CloseReason cr = -new CloseReason(CloseCodes.CLOSED_ABNORMALLY, ioe.getMessage()); +CloseReason cr = new CloseReason(CloseCodes.CLOSED_ABNORMALLY, ioe.getMessage()); try { session.close(cr); } catch (IOException ioe2) { diff --git a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java index 37b1cf9626..442b5885ee 100644 --- a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java +++ b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java @@ -75,6 +75,9 @@ public class SnakeAnnotation { @OnOpen public void onOpen(Session session) { +// If the messages take longer than TICK_DELAY to be sent, the game isn't going to work properly. + session.getUserProperties().put("org.apache.tomcat.websocket.BLOCKING_SEND_TIMEOUT", +Long.valueOf(SnakeTimer.TICK_DELAY)); this.snake = new Snake(id, session); SnakeTimer.addSnake(snake); StringBuilder sb = new StringBuilder(); @@ -87,8 +90,7 @@ public class SnakeAnnotation { sb.append(','); } } -SnakeTimer.broadcast(String.format("{\"type\": \"join\",\"data\":[%s]}", -sb.toString())); +SnakeTimer.broadcast(String.format("{\"type\": \"join\",\"data\":[%s]}", sb.toString())); } @@ -109,8 +111,7 @@ public class SnakeAnnotation { @OnClose public void onClose() { SnakeTimer.removeSnake(snake); -SnakeTimer.broadcast(String.format("{\"type\": \"leave\", \"id\": %d}", -Integer.valueOf(id))); +SnakeTimer.broadcast(String.format("{\"type\": \"leave\", \"id\": %d}", Integer.valueOf(id))); } diff --git a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer.java b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer.java index 6b777e94e3..872f2dcddc 100644 --- a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer.java +++ b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeTimer.java @@ -36,7 +36,7 @@ public class SnakeTimer { private static Timer gameTimer = null; -private static final long TICK_DELAY = 100; +static final long TICK_DELAY = 100; private static final ConcurrentHashMap snakes = new ConcurrentHashMap<>(); @@ -73,8 +73,7 @@ public class SnakeTimer { sb.append(','); } } -broadcast(String.format("{\"type\": \"update\", \"data\" : [%s]}", -sb.toString())); +broadcast(String.format("{\"type\": \"update\", \"data\" : [%s]}", sb.toString())); } protected static void broadcast(String message) { - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
(tomcat) branch 9.0.x updated: Remove duplicate leave notification
This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git The following commit(s) were added to refs/heads/9.0.x by this push: new 06f336b6e4 Remove duplicate leave notification 06f336b6e4 is described below commit 06f336b6e4109b688bde1f54bde44fb2f13b2e9e Author: Mark Thomas AuthorDate: Wed May 1 17:16:06 2024 +0100 Remove duplicate leave notification session.close() will trigger onClose() exactly once --- webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java | 1 - 1 file changed, 1 deletion(-) diff --git a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java index d3d9700021..84ed091b3f 100644 --- a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java +++ b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java @@ -120,7 +120,6 @@ public class SnakeAnnotation { * Assume all errors are fatal. Close the session and remove the snake from the game. */ session.close(); -onClose(); /* * Correct action depends on root cause. Protect against infinite loops while looking for root cause. */ - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
(tomcat) branch 10.1.x updated: Remove duplicate leave notification
This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 10.1.x in repository https://gitbox.apache.org/repos/asf/tomcat.git The following commit(s) were added to refs/heads/10.1.x by this push: new a8c4b9c27a Remove duplicate leave notification a8c4b9c27a is described below commit a8c4b9c27a20e1527b4bf3afe537a6d01bb9fb4f Author: Mark Thomas AuthorDate: Wed May 1 17:16:06 2024 +0100 Remove duplicate leave notification session.close() will trigger onClose() exactly once --- webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java | 1 - 1 file changed, 1 deletion(-) diff --git a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java index 7f14ab8cca..37b1cf9626 100644 --- a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java +++ b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java @@ -120,7 +120,6 @@ public class SnakeAnnotation { * Assume all errors are fatal. Close the session and remove the snake from the game. */ session.close(); -onClose(); /* * Correct action depends on root cause. Protect against infinite loops while looking for root cause. */ - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
(tomcat) branch main updated: Remove duplicate leave notification
This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git The following commit(s) were added to refs/heads/main by this push: new 4571b30eb9 Remove duplicate leave notification 4571b30eb9 is described below commit 4571b30eb912f2f7602f721f1c0ed2d79f77db68 Author: Mark Thomas AuthorDate: Wed May 1 17:16:06 2024 +0100 Remove duplicate leave notification session.close() will trigger onClose() exactly once --- webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java | 1 - 1 file changed, 1 deletion(-) diff --git a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java index 7f14ab8cca..37b1cf9626 100644 --- a/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java +++ b/webapps/examples/WEB-INF/classes/websocket/snake/SnakeAnnotation.java @@ -120,7 +120,6 @@ public class SnakeAnnotation { * Assume all errors are fatal. Close the session and remove the snake from the game. */ session.close(); -onClose(); /* * Correct action depends on root cause. Protect against infinite loops while looking for root cause. */ - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
(tomcat) 01/02: Improve handling of concurrent disconnects
This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git commit b779a10c6a45c1531690fe2f67e9e7722c35cade Author: Mark Thomas AuthorDate: Wed May 1 12:31:07 2024 +0100 Improve handling of concurrent disconnects --- webapps/docs/changelog.xml | 8 +++ .../classes/websocket/chat/ChatAnnotation.java | 71 -- 2 files changed, 60 insertions(+), 19 deletions(-) diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 5217123962..7eda587865 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -194,6 +194,14 @@ + + + +Examples: Improve performance of WebSocket chat application when +multiple clients disconnect at the same time. (markt) + + + diff --git a/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java b/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java index d1d55234da..dee5c4e5ab 100644 --- a/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java +++ b/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java @@ -17,6 +17,8 @@ package websocket.chat; import java.io.IOException; +import java.util.ArrayDeque; +import java.util.Queue; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.atomic.AtomicInteger; @@ -40,11 +42,16 @@ public class ChatAnnotation { private static final String GUEST_PREFIX = "Guest"; private static final AtomicInteger connectionIds = new AtomicInteger(0); -private static final Set connections = -new CopyOnWriteArraySet<>(); +private static final Set connections = new CopyOnWriteArraySet<>(); private final String nickname; private Session session; +/* + * The queue of messages that may build up while another message is being sent. The thread that sends a message is + * responsible for clearing any queue that builds up while that message is being sent. + */ +private Queue messageBacklog = new ArrayDeque<>(); +private boolean messageInProgress = false; public ChatAnnotation() { nickname = GUEST_PREFIX + connectionIds.getAndIncrement(); @@ -63,8 +70,7 @@ public class ChatAnnotation { @OnClose public void end() { connections.remove(this); -String message = String.format("* %s %s", -nickname, "has disconnected."); +String message = String.format("* %s %s", nickname, "has disconnected."); broadcast(message); } @@ -72,37 +78,64 @@ public class ChatAnnotation { @OnMessage public void incoming(String message) { // Never trust the client -String filteredMessage = String.format("%s: %s", -nickname, HTMLFilter.filter(message.toString())); +String filteredMessage = String.format("%s: %s", nickname, HTMLFilter.filter(message.toString())); broadcast(filteredMessage); } - - @OnError public void onError(Throwable t) throws Throwable { log.error("Chat Error: " + t.toString(), t); } +/* + * synchronized blocks are limited to operations that are expected to be quick. More specifically, messages are not + * sent from within a synchronized block. + */ +private void sendMessage(String msg) throws IOException { + +synchronized (this) { +if (messageInProgress) { +messageBacklog.add(msg); +return; +} else { +messageInProgress = true; +} +} + +boolean queueHasMessagesToBeSent = true; + +String messageToSend = msg; +do { +session.getBasicRemote().sendText(messageToSend); +synchronized (this) { +messageToSend = messageBacklog.poll(); +if (messageToSend == null) { +messageInProgress = false; +queueHasMessagesToBeSent = false; +} +} + +} while (queueHasMessagesToBeSent); + } + + private static void broadcast(String msg) { for (ChatAnnotation client : connections) { try { -synchronized (client) { -client.session.getBasicRemote().sendText(msg); -} +client.sendMessage(msg); } catch (IOException e) { log.debug("Chat Error: Failed to send message to client", e); -connections.remove(client); -try { -client.session.close(); -} catch (IOException e1) { -// Ignore +if (connections.remove(client)) { +try { +client.session.close(); +
(tomcat) 02/02: Increase scrollback
This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git commit 86c148cbd9c045e12f09b87c5933e144655148b5 Author: Mark Thomas AuthorDate: Wed May 1 12:32:36 2024 +0100 Increase scrollback Originally for debugging but viewed as generally useful. --- webapps/docs/changelog.xml| 4 webapps/examples/websocket/chat.xhtml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 7eda587865..85e4c780a1 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -200,6 +200,10 @@ Examples: Improve performance of WebSocket chat application when multiple clients disconnect at the same time. (markt) + +Examples: Increase the number of previous messages displayed when using +the WebSocket chat application. (markt) + diff --git a/webapps/examples/websocket/chat.xhtml b/webapps/examples/websocket/chat.xhtml index 6c863feafa..f5b4dc3579 100644 --- a/webapps/examples/websocket/chat.xhtml +++ b/webapps/examples/websocket/chat.xhtml @@ -31,7 +31,7 @@ border: 1px solid #CC; border-right-color: #99; border-bottom-color: #99; -height: 170px; +height: 600px; overflow-y: scroll; padding: 5px; width: 100%; @@ -102,7 +102,7 @@ p.style.wordWrap = 'break-word'; p.innerHTML = message; console.appendChild(p); -while (console.childNodes.length > 25) { +while (console.childNodes.length > 100) { console.removeChild(console.firstChild); } console.scrollTop = console.scrollHeight; - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
(tomcat) branch 9.0.x updated (75d8aed87c -> 86c148cbd9)
This is an automated email from the ASF dual-hosted git repository. markt pushed a change to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git from 75d8aed87c Javadoc cleanup for Catalina new b779a10c6a Improve handling of concurrent disconnects new 86c148cbd9 Increase scrollback The 2 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "add" were already present in the repository and have only been added to this reference. Summary of changes: webapps/docs/changelog.xml | 12 .../classes/websocket/chat/ChatAnnotation.java | 71 -- webapps/examples/websocket/chat.xhtml | 4 +- 3 files changed, 66 insertions(+), 21 deletions(-) - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
(tomcat) 01/02: Improve handling of concurrent disconnects
This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 10.1.x in repository https://gitbox.apache.org/repos/asf/tomcat.git commit 39f75945410ef5412e7f9a0804bb0b3ce5535640 Author: Mark Thomas AuthorDate: Wed May 1 12:31:07 2024 +0100 Improve handling of concurrent disconnects --- webapps/docs/changelog.xml | 8 +++ .../classes/websocket/chat/ChatAnnotation.java | 71 -- 2 files changed, 60 insertions(+), 19 deletions(-) diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 18667ad683..87b5b4bf5d 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -185,6 +185,14 @@ + + + +Examples: Improve performance of WebSocket chat application when +multiple clients disconnect at the same time. (markt) + + + diff --git a/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java b/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java index c0a2f2b515..337e08024d 100644 --- a/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java +++ b/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java @@ -17,6 +17,8 @@ package websocket.chat; import java.io.IOException; +import java.util.ArrayDeque; +import java.util.Queue; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.atomic.AtomicInteger; @@ -40,11 +42,16 @@ public class ChatAnnotation { private static final String GUEST_PREFIX = "Guest"; private static final AtomicInteger connectionIds = new AtomicInteger(0); -private static final Set connections = -new CopyOnWriteArraySet<>(); +private static final Set connections = new CopyOnWriteArraySet<>(); private final String nickname; private Session session; +/* + * The queue of messages that may build up while another message is being sent. The thread that sends a message is + * responsible for clearing any queue that builds up while that message is being sent. + */ +private Queue messageBacklog = new ArrayDeque<>(); +private boolean messageInProgress = false; public ChatAnnotation() { nickname = GUEST_PREFIX + connectionIds.getAndIncrement(); @@ -63,8 +70,7 @@ public class ChatAnnotation { @OnClose public void end() { connections.remove(this); -String message = String.format("* %s %s", -nickname, "has disconnected."); +String message = String.format("* %s %s", nickname, "has disconnected."); broadcast(message); } @@ -72,37 +78,64 @@ public class ChatAnnotation { @OnMessage public void incoming(String message) { // Never trust the client -String filteredMessage = String.format("%s: %s", -nickname, HTMLFilter.filter(message.toString())); +String filteredMessage = String.format("%s: %s", nickname, HTMLFilter.filter(message.toString())); broadcast(filteredMessage); } - - @OnError public void onError(Throwable t) throws Throwable { log.error("Chat Error: " + t.toString(), t); } +/* + * synchronized blocks are limited to operations that are expected to be quick. More specifically, messages are not + * sent from within a synchronized block. + */ +private void sendMessage(String msg) throws IOException { + +synchronized (this) { +if (messageInProgress) { +messageBacklog.add(msg); +return; +} else { +messageInProgress = true; +} +} + +boolean queueHasMessagesToBeSent = true; + +String messageToSend = msg; +do { +session.getBasicRemote().sendText(messageToSend); +synchronized (this) { +messageToSend = messageBacklog.poll(); +if (messageToSend == null) { +messageInProgress = false; +queueHasMessagesToBeSent = false; +} +} + +} while (queueHasMessagesToBeSent); + } + + private static void broadcast(String msg) { for (ChatAnnotation client : connections) { try { -synchronized (client) { -client.session.getBasicRemote().sendText(msg); -} +client.sendMessage(msg); } catch (IOException e) { log.debug("Chat Error: Failed to send message to client", e); -connections.remove(client); -try { -client.session.close(); -} catch (IOException e1) { -// Ignore +if (connections.remove(client)) { +try { +client.session.close(); +
(tomcat) 02/02: Increase scrollback
This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 10.1.x in repository https://gitbox.apache.org/repos/asf/tomcat.git commit ea40f2ed7abc17769e9ae6fb674f79d5e5f964ef Author: Mark Thomas AuthorDate: Wed May 1 12:32:36 2024 +0100 Increase scrollback Originally for debugging but viewed as generally useful. --- webapps/docs/changelog.xml| 4 webapps/examples/websocket/chat.xhtml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 87b5b4bf5d..3e6114bda0 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -191,6 +191,10 @@ Examples: Improve performance of WebSocket chat application when multiple clients disconnect at the same time. (markt) + +Examples: Increase the number of previous messages displayed when using +the WebSocket chat application. (markt) + diff --git a/webapps/examples/websocket/chat.xhtml b/webapps/examples/websocket/chat.xhtml index 6c863feafa..f5b4dc3579 100644 --- a/webapps/examples/websocket/chat.xhtml +++ b/webapps/examples/websocket/chat.xhtml @@ -31,7 +31,7 @@ border: 1px solid #CC; border-right-color: #99; border-bottom-color: #99; -height: 170px; +height: 600px; overflow-y: scroll; padding: 5px; width: 100%; @@ -102,7 +102,7 @@ p.style.wordWrap = 'break-word'; p.innerHTML = message; console.appendChild(p); -while (console.childNodes.length > 25) { +while (console.childNodes.length > 100) { console.removeChild(console.firstChild); } console.scrollTop = console.scrollHeight; - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
(tomcat) branch 10.1.x updated (2ce8e9ebf4 -> ea40f2ed7a)
This is an automated email from the ASF dual-hosted git repository. markt pushed a change to branch 10.1.x in repository https://gitbox.apache.org/repos/asf/tomcat.git from 2ce8e9ebf4 Javadoc cleanup for Catalina new 39f7594541 Improve handling of concurrent disconnects new ea40f2ed7a Increase scrollback The 2 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "add" were already present in the repository and have only been added to this reference. Summary of changes: webapps/docs/changelog.xml | 12 .../classes/websocket/chat/ChatAnnotation.java | 71 -- webapps/examples/websocket/chat.xhtml | 4 +- 3 files changed, 66 insertions(+), 21 deletions(-) - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
(tomcat) branch main updated (5a90d88c86 -> 4b1e0f1d7b)
This is an automated email from the ASF dual-hosted git repository. markt pushed a change to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git from 5a90d88c86 Javadoc cleanup for Catalina new 8f62c52a79 Improve handling of concurrent disconnects new 4b1e0f1d7b Increase scrollback The 2 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "add" were already present in the repository and have only been added to this reference. Summary of changes: webapps/docs/changelog.xml | 12 .../classes/websocket/chat/ChatAnnotation.java | 71 -- webapps/examples/websocket/chat.xhtml | 4 +- 3 files changed, 66 insertions(+), 21 deletions(-) - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
(tomcat) 02/02: Increase scrollback
This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git commit 4b1e0f1d7b4ae1f7a4824df93363821e57c422ff Author: Mark Thomas AuthorDate: Wed May 1 12:32:36 2024 +0100 Increase scrollback Originally for debugging but viewed as generally useful. --- webapps/docs/changelog.xml| 4 webapps/examples/websocket/chat.xhtml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 0e929662fa..e0ccec8de6 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -213,6 +213,10 @@ Examples: Improve performance of WebSocket chat application when multiple clients disconnect at the same time. (markt) + +Examples: Increase the number of previous messages displayed when using +the WebSocket chat application. (markt) + diff --git a/webapps/examples/websocket/chat.xhtml b/webapps/examples/websocket/chat.xhtml index 6c863feafa..f5b4dc3579 100644 --- a/webapps/examples/websocket/chat.xhtml +++ b/webapps/examples/websocket/chat.xhtml @@ -31,7 +31,7 @@ border: 1px solid #CC; border-right-color: #99; border-bottom-color: #99; -height: 170px; +height: 600px; overflow-y: scroll; padding: 5px; width: 100%; @@ -102,7 +102,7 @@ p.style.wordWrap = 'break-word'; p.innerHTML = message; console.appendChild(p); -while (console.childNodes.length > 25) { +while (console.childNodes.length > 100) { console.removeChild(console.firstChild); } console.scrollTop = console.scrollHeight; - To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org
(tomcat) 01/02: Improve handling of concurrent disconnects
This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git commit 8f62c52a79c5c35ee8a22f9de43d09a2461e4a7d Author: Mark Thomas AuthorDate: Wed May 1 12:31:07 2024 +0100 Improve handling of concurrent disconnects --- webapps/docs/changelog.xml | 8 +++ .../classes/websocket/chat/ChatAnnotation.java | 71 -- 2 files changed, 60 insertions(+), 19 deletions(-) diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index aa190cbae4..0e929662fa 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -207,6 +207,14 @@ + + + +Examples: Improve performance of WebSocket chat application when +multiple clients disconnect at the same time. (markt) + + + diff --git a/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java b/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java index c0a2f2b515..337e08024d 100644 --- a/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java +++ b/webapps/examples/WEB-INF/classes/websocket/chat/ChatAnnotation.java @@ -17,6 +17,8 @@ package websocket.chat; import java.io.IOException; +import java.util.ArrayDeque; +import java.util.Queue; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.atomic.AtomicInteger; @@ -40,11 +42,16 @@ public class ChatAnnotation { private static final String GUEST_PREFIX = "Guest"; private static final AtomicInteger connectionIds = new AtomicInteger(0); -private static final Set connections = -new CopyOnWriteArraySet<>(); +private static final Set connections = new CopyOnWriteArraySet<>(); private final String nickname; private Session session; +/* + * The queue of messages that may build up while another message is being sent. The thread that sends a message is + * responsible for clearing any queue that builds up while that message is being sent. + */ +private Queue messageBacklog = new ArrayDeque<>(); +private boolean messageInProgress = false; public ChatAnnotation() { nickname = GUEST_PREFIX + connectionIds.getAndIncrement(); @@ -63,8 +70,7 @@ public class ChatAnnotation { @OnClose public void end() { connections.remove(this); -String message = String.format("* %s %s", -nickname, "has disconnected."); +String message = String.format("* %s %s", nickname, "has disconnected."); broadcast(message); } @@ -72,37 +78,64 @@ public class ChatAnnotation { @OnMessage public void incoming(String message) { // Never trust the client -String filteredMessage = String.format("%s: %s", -nickname, HTMLFilter.filter(message.toString())); +String filteredMessage = String.format("%s: %s", nickname, HTMLFilter.filter(message.toString())); broadcast(filteredMessage); } - - @OnError public void onError(Throwable t) throws Throwable { log.error("Chat Error: " + t.toString(), t); } +/* + * synchronized blocks are limited to operations that are expected to be quick. More specifically, messages are not + * sent from within a synchronized block. + */ +private void sendMessage(String msg) throws IOException { + +synchronized (this) { +if (messageInProgress) { +messageBacklog.add(msg); +return; +} else { +messageInProgress = true; +} +} + +boolean queueHasMessagesToBeSent = true; + +String messageToSend = msg; +do { +session.getBasicRemote().sendText(messageToSend); +synchronized (this) { +messageToSend = messageBacklog.poll(); +if (messageToSend == null) { +messageInProgress = false; +queueHasMessagesToBeSent = false; +} +} + +} while (queueHasMessagesToBeSent); + } + + private static void broadcast(String msg) { for (ChatAnnotation client : connections) { try { -synchronized (client) { -client.session.getBasicRemote().sendText(msg); -} +client.sendMessage(msg); } catch (IOException e) { log.debug("Chat Error: Failed to send message to client", e); -connections.remove(client); -try { -client.session.close(); -} catch (IOException e1) { -// Ignore +if (connections.remove(client)) { +try { +client.session.close(); +