Description
When listen to unix socket, socket file are not removed when stopping gin process (use Ctrl + C
). The next time it is executed, the process will report an error: [GIN-debug] [ERROR] listen unix /tmp/testgin.sock: bind: address already in use
How to reproduce
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
file := "/tmp/testgin.sock"
//os.Remove(file)
r.RunUnix(file)
}
Environment
- go version: v1.20.3
- gin version (or commit ref): v1.9.1
- operating system: osx, ubuntu
Comment From: ismdeep
2280
Comment From: howcrazy
The socket should instead be cleaned up at shutdown.
It creates the sock file but does not delete it after Ctrl + C or stop by supervisord. defer os.Remove(file)
not executed.
Maybe I should handle this situation manually?
Comment From: openarun
+1
Comment From: daftaupe
The socket should instead be cleaned up at shutdown.
It creates the sock file but does not delete it after Ctrl + C or stop by supervisord.
defer os.Remove(file)
not executed.Maybe I should handle this situation manually?
I don't think you should have to, if the service is not running anymore, the socket should disappear imo.
Comment From: howcrazy
The socket should instead be cleaned up at shutdown.
It creates the sock file but does not delete it after Ctrl + C or stop by supervisord.
defer os.Remove(file)
not executed. Maybe I should handle this situation manually?I don't think you should have to, if the service is not running anymore, the socket should disappear imo.
But it still there 😂
Comment From: XANi
I looked into it a bit and it's some really weird problem.
For context, simple unix socket
func main() {
l, err := net.Listen("unix", "sock")
fmt.Println(err)
defer l.Close()
}
will get removed without any extra cleanup but the moment builtin Go stuff in involved, socket gets stale:
package main
import (
"fmt"
"net"
"net/http"
)
type H struct{}
func (h *H) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
func main() {
u, err := net.Listen("unix", "sock")
fmt.Println(err)
if err == nil {
defer u.Close()
fmt.Println("press C-c and run me again")
fmt.Println(http.Serve(u, &H{}))
}
}
TL;DR nothing Gin can really do here. https://github.com/golang/go/issues/70985