I'm building a chat server using Go and Socket.io hence the server would be running indefinitely. There are multiple resources which I need allocated upon the start of the program such as the database connection, redis connection, etc.
Now I'm wondering when all these connections should be released (closed)? Can I use defer
in the main
function? Does that close them when main
reaches its end? Or should I just leave 'em open since the program will not exit on its own accord?
One thing I tend to do is this:
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
func run() error {
// Do stuff here
}
In run
you can then defer
as you are used to. However, in a long-running program like a server, IMO it's fine to just exit: The OS will clean up all resources taken up by the process automatically and whatever database or backend you have a connection to, has to be able to handle the process dying unexpectedly anyway. This is called "crash-only software".
For tests, you should build your code in a way that it doesn't depend on global state - e.g. have a struct that has fields for the database connections etc. Make the business logic a method on that struct (or a function taking it). You can then in your main
populate such a struct and call its methods. And for testing, you can populate a struct, call its methods for whatever tests you want to do and then tear down the connections at the end of your test.