You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When running NATS embedded in go, if you start the server then create a context from a system signal, such as SIGTERM, and
call server.Shutdown() on that contexts cancellation, it will cause a "close of nil channel" panic in server.(*Server).shutdownEventing.
server.(*Server).isRunning() returns the result from the Server.running atomic bool, which will return true, because it is only set to false in later in server.(*Server).Shutdown()
isRunning() returns true
eventsRunning() returns true
shutdownEventing() now thinks the server is running so it continues, and tries to close rc on line 1826 even though it will be nil.
Expected behavior
Multiple simultaneous calls shouldn't cause server.Shutdown() to panic.
Server and client version
server: v2.10.22
client: N/A
Host environment
OS: NixOS 24.11
CPU architecture: x86_64
Steps to reproduce
Steps
Create and start an embedded nats-server in a Go program.
Wait till server is ready for connections.
Create a signal notify context (such as SIGTERM)
Call server.Shutdown() when the signal's done channel is closed.
You s should set NoSigs on the options structure to avoid double signal handling.
Typically I would do that however the bug was discovered from a wrapper library that provides a Shutdown function with a timeout context. If that function checks if the nats-server has NoSigs set to true, then it can just call Shutdown without any worry, however, if NoSigs is set to false then it doesn't know if nats-server is already handling the shutdown, and should just wait till it's done, or call Shutdown itself since ns.Running() (in the example provided) returns true.
Observed behavior
When running NATS embedded in go, if you start the server then create a context from a system signal, such as SIGTERM, and
call server.Shutdown() on that contexts cancellation, it will cause a "close of nil channel" panic in
server.(*Server).shutdownEventing
.I believe this is due to these chains of events:
server.(*Server).Shutdown()
callsserver.(*Server).shutdownEventing()
server.(*Server).shutdownEventing()
first callsserver.(*Server).eventsRunning()
server.(*Server).eventsRunning()
callsserver.(*Server).isRunning()
server.(*Server).isRunning()
returns the result from theServer.running
atomic bool, which will return true, because it is only set to false in later inserver.(*Server).Shutdown()
isRunning()
returns trueeventsRunning()
returns trueshutdownEventing()
now thinks the server is running so it continues, and tries to close rc on line 1826 even though it will be nil.Expected behavior
Multiple simultaneous calls shouldn't cause
server.Shutdown()
to panic.Server and client version
server: v2.10.22
client: N/A
Host environment
OS: NixOS 24.11
CPU architecture: x86_64
Steps to reproduce
Steps
server.Shutdown()
when the signal's done channel is closed.Example
The text was updated successfully, but these errors were encountered: