Reputation: 1078
i am using go-diameter library to write a simple Diameter server. Reading and understanding the basic working through the example files provided i am able to start a Diameter server and it is serving requests as expected.
The only issue i am facing is how to stop the server. I searched through whole source code but i didn't find any explicit way to graceful stop the server so that it can return from ListenAndServer.. functions.
diam.ListenAndServe(addr, handler, nil)
i liked the mux logic they have implemented so i preferably don't want to write the bare server (that they have showed in one of the example).
Upvotes: 1
Views: 104
Reputation: 1078
I didn't want to loose the mux way of handling diameter requests and responses but i couldn't find any API to gracefully stop a diameter server started with ListenAnd...() family of functions.
So i switched to the bare server example. But there also i faced with an issue.
if conn, err := srv.Accept(); err != nil {
is a blocking call and closing the server socket does not make Accept to return for some reason. I tried making the socket non-blocking but then it does not handle EAGAIN.
i think this is SCTP specific issue ONLY.
here is the final version i wrote.
e, err := sctp.MakeSCTPAddr("sctp4", config.localEndpoint)
l, err = sctp.ListenSCTP("sctp4", syscall.SOCK_STREAM,
e,
&sctp.SCTPInitMsg{
NumOutStreams: uint16(10),
MaxInStreams: uint16(10),
MaxAttempts: 3,
MaxInitTimeout: 5,
},
)
defer l.Close()
l.(*sctp.SCTPListener).SetNonblock()
for {
select {
case <-ctx.Done():
p.logger.Info("exiting...")
return
default:
conn, err := l.Accept()
if err != nil {
switch v := err.(type) {
case syscall.Errno:
if v == 11 {
// handle EAGAIN error, typical error for non-blocking sockets
time.Sleep(50 * time.Millisecond)
}
}
} else {
go handleClient(conn)
}
}
}
Upvotes: 0