Exit cleanup and resource release

A more practical and common example of a clean shutdown is resource cleanup. When using exit statements, deferred functions such as Flush for a bufio.Writer struct are not executed. This can lead to information loss, as shown in the following example:

package main

import (
"bufio"
"fmt"
"log"
"os"
"time"
)

func main() {
f, err := os.OpenFile("file.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
if err != nil {
log.Fatal(err)
}
defer f.Close()
w := bufio.NewWriter(f)
defer w.Flush()
for i := 0; i < 3; i++ {
fmt.Fprintln(w, "hello")
log.Println(i)
time.Sleep(time.Second)
}
}

If a TERM signal is sent to this application before it finishes, the file will be created and truncated, but the flush will never be executed—resulting in an empty file.

This could, perhaps, be the intended behavior, but this is rarely the case. It is better to do any cleanup in the signal handling part, as shown in the following example:

func main() {
c := make(chan os.Signal, syscall.SIGTERM)
signal.Notify(c)
f, err := os.OpenFile("file.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
if err != nil {
log.Fatal(err)
}
defer f.Close()
w := bufio.NewWriter(f)
go func() {
<-c
w.Flush()
os.Exit(0)
}()
for i := 0; i < 3; i++ {
fmt.Fprintln(w, "hello")
log.Println(i)
time.Sleep(time.Second)
}
}

In this case, we are using a goroutine in combination with the signal channel to flush the writer before exiting. This will ensure that whatever is written to the buffer gets persisted on the file.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.78.136