Defer on exit

Working with go, sometimes you may want to run a deferred action on Exit. Something like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package main

import (
    "fmt"
    "os"
)

func main() {
    // THIS WILL NOT WORK
    defer fmt.Println("World")
    fmt.Println("Hello")

    // some code here...

    os.Exit(0)
}

In the above code, World will never get printed. This is because defer is not run on os.Exit.

One pattern to fix this is to have main call another function that does the real work. Defer on that function will work e.g.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package main

import (
    "fmt"
    "os"
)

func main() {
    os.Exit(mainWorker())
}

func mainWorker() int {
    defer fmt.Println("World")
    fmt.Println("Hello")

    // some code here...

    return 0
}

The above snipper correctly prints:

Hello
World

You can see real world usage of this pattern in Packer