fergusstrange / embedded-postgres

Run a real Postgres database locally on Linux, OSX or Windows as part of another Go application or test
MIT License
854 stars 89 forks source link

defer not working, and so DB not getting shutdown. #55

Closed gedw99 closed 2 years ago

gedw99 commented 2 years ago

Can someone help me with why this code does not call the embeddedPostgres.Stop() ?

There is a sleep forever to simulate work being done.

This also means that on the 2nd run, the execution fails with:

2021/11/20 12:35:01 process already listening on port 5432
package main

import (
    "log"

    embeddedpostgres "github.com/fergusstrange/embedded-postgres"
)

func main() {

    embeddedPostgres := embeddedpostgres.NewDatabase()
    if err := embeddedPostgres.Start(); err != nil {
        log.Fatal(err)
    }
    defer func() {
        if err := embeddedPostgres.Stop(); err != nil {
            log.Fatal(err)
        }
    }()

    log.Println("ready ...")

    // sleep forever
    blockForever()

}

func blockForever() {
    select {}
}
survivorbat commented 2 years ago

The only way of stopping your program during the infinite block is to terminate it in the terminal, right? I don't think that immediate shutdown accounts for defers.

I do think it'll work if the sleeping block panics at any point.

fergusstrange commented 2 years ago

Hi @gedw99 the way GoLang works, that defer statement will only run once the main method completes. In this case you have another method blocking forever which will prevent the main() method from completing and the defer being run. As mentioned by @survivorbat this won't be called if you close your program forcefully with ctrl + c or any other forceful method.

Here's a great guide to how defer works.

If you wish to gracefully close the program by catching the sigterm sent then calling .Stop() you can do something similar to the method described here.

Let me know how you go!

gedw99 commented 2 years ago

thanks for the tips. Will try out your suggestions and let you know !!