Skip to content

Commit 0a14896

Browse files
committed
* sse: fixed memory leak under heavy load
Signed-off-by: neo <1100909+neowu@users.noreply.github.com>
1 parent 081e5bc commit 0a14896

File tree

3 files changed

+13
-5
lines changed

3 files changed

+13
-5
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
* migrate from ThreadLocal to ScopedValue
1111
> updated WebContext
1212
> updated LogManager
13+
* sse: fixed memory leak under heavy load
14+
> exchange was not properly closed under heavy IO + throwing error on connect
1315
1416
### 9.2.4 (8/8/2025 - 8/21/2025)
1517

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ plugins {
66

77
subprojects {
88
group = "core.framework"
9-
version = "9.3.0-b1"
9+
version = "9.3.0-b2"
1010
repositories {
1111
maven {
1212
url = uri("https://neowu.github.io/maven-repo/")

core-ng/src/main/java/core/framework/internal/web/sse/ChannelImpl.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,16 @@ public void close() {
103103
lock.lock();
104104
if (closed) return;
105105

106-
closed = true;
107-
if (queue.isEmpty()) {
108-
exchange.endExchange();
106+
// for flow like
107+
// channel.sendBytes("error");
108+
// channel.close();
109+
// the close logic (this closure) could run first in different IO thread while sendBytes is blocked due to lock
110+
// so here we should try to send remaining messages in queue before close
111+
if (!queue.isEmpty()) {
112+
writeListener.handleEvent(sink);
109113
}
114+
exchange.endExchange();
115+
closed = true; // make sure mark closed after endExchange, to make sure no leak of exchange
110116
} finally {
111117
lock.unlock();
112118
}
@@ -119,9 +125,9 @@ public void shutdown() {
119125
if (closed) return;
120126

121127
LOGGER.debug("shutdown sse connection, channel={}", id);
122-
closed = true;
123128
queue.clear();
124129
exchange.endExchange();
130+
closed = true; // make sure mark closed after endExchange, to make sure no leak of exchange
125131
} finally {
126132
lock.unlock();
127133
}

0 commit comments

Comments
 (0)