vk-code
vk-code

Reputation: 1078

how to stop the go-diameter server

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

Answers (1)

vk-code
vk-code

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

Related Questions