From 20b1676590bf9da5070ee5eb487fb58f86a1e884 Mon Sep 17 00:00:00 2001 From: Alex Hultman Date: Wed, 20 May 2020 17:10:20 +0200 Subject: [PATCH] Skip sending rather than immediately close while publishing --- src/WebSocketContextData.h | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/WebSocketContextData.h b/src/WebSocketContextData.h index 1f0d1ac..ac94868 100644 --- a/src/WebSocketContextData.h +++ b/src/WebSocketContextData.h @@ -60,17 +60,21 @@ struct WebSocketContextData { /* We rely on writing to regular asyncSockets */ auto *asyncSocket = (AsyncSocket *) s->user; - auto [written, failed] = asyncSocket->write(data.data(), (int) data.length()); - if (!failed) { - asyncSocket->timeout(this->idleTimeout); - } else { + /* Check if we now have too much backpressure (todo: don't buffer up before check) */ + if (!maxBackpressure || (unsigned int) asyncSocket->getBufferedAmount() < maxBackpressure) { + /* Note: this assumes we are not corked, as corking will swallow things and fail later on */ - - /* Check if we now have too much backpressure (todo: don't buffer up before check) */ - if ((unsigned int) asyncSocket->getBufferedAmount() > maxBackpressure) { - asyncSocket->close(); + auto [written, failed] = asyncSocket->write(data.data(), (int) data.length()); + if (!failed) { + asyncSocket->timeout(this->idleTimeout); } + + /* Failing here must not immediately close the socket, as that could result in stack overflow, + * iterator invalidation and other TopicTree::drain bugs. We may shutdown the reading side of the socket, + * causing next iteration to error-close the socket from that context instead, if we want to */ } + + /* If we have too much backpressure, simply skip sending from here */ /* Reserved, unused */ return 0;