Environment: OneDev server 16.7.3, agent 3.3.1 (macOS arm64, Temurin 27, Tanuki wrapper). The same code is present in agent 3.3.9 and current main (AgentSocket.java).
Symptom: after the agent's websocket connection drops (laptop sleep / network change), the agent java process keeps one core busy (80–90%) indefinitely. The agent itself reconnects and keeps working, but the CPU never goes down until the agent is restarted. Over 3 days we measured ~66 h of CPU time on a single thread.
Thread dump (two samples, same thread):
"Thread-439" cpu=239470399ms elapsed=248339s RUNNABLE
at java.lang.Thread.sleep(Thread.java:593)
at io.onedev.agent.AgentSocket.onClose(AgentSocket.java:555)
at org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandler.notifyOnClose(...)
at org.eclipse.jetty.websocket.core.WebSocketCoreSession.closeConnection(...)
at org.eclipse.jetty.websocket.core.WebSocketCoreSession.processConnectionError(...)
at org.eclipse.jetty.websocket.core.WebSocketConnection$Flusher.onFailure(...)
...
at io.onedev.agent.Message.sendBy(Message.java:50)
at io.onedev.agent.AgentSocket.run(AgentSocket.java:1587)
at java.lang.Thread.run(Thread.java:1527)
The second sample shows the same thread in InterruptedException.<init>.
Cause (as we read the code): the heartbeat thread (new Thread(this) in onConnect, running AgentSocket.run) sends a message; the send fails on a closed channel, and Jetty invokes onClose synchronously on that same thread. onClose does
Here thread is the current thread, so it interrupts itself, sleep throws immediately, and stopped is only set by run() – which is blocked inside onClose. The loop never exits and never sleeps.
Suggested fix: in onClose, skip the interrupt/wait loop when Thread.currentThread() == thread (or set stopped = true before returning in that case / in a finally of run()).
Workaround we use: restarting the agent (launchctl kickstart -k) once a day.
Environment: OneDev server 16.7.3, agent 3.3.1 (macOS arm64, Temurin 27, Tanuki wrapper). The same code is present in agent 3.3.9 and current main (AgentSocket.java).
Symptom: after the agent's websocket connection drops (laptop sleep / network change), the agent java process keeps one core busy (80–90%) indefinitely. The agent itself reconnects and keeps working, but the CPU never goes down until the agent is restarted. Over 3 days we measured ~66 h of CPU time on a single thread.
Thread dump (two samples, same thread):
The second sample shows the same thread in
InterruptedException.<init>.Cause (as we read the code): the heartbeat thread (
new Thread(this)inonConnect, runningAgentSocket.run) sends a message; the send fails on a closed channel, and Jetty invokesonClosesynchronously on that same thread.onClosedoesHere
threadis the current thread, so it interrupts itself,sleepthrows immediately, andstoppedis only set byrun()– which is blocked insideonClose. The loop never exits and never sleeps.Suggested fix: in
onClose, skip the interrupt/wait loop whenThread.currentThread() == thread(or setstopped = truebefore returning in that case / in afinallyofrun()).Workaround we use: restarting the agent (
launchctl kickstart -k) once a day.