Book Image

Go Standard Library Cookbook

By : Radomír Sohlich
Book Image

Go Standard Library Cookbook

By: Radomír Sohlich

Overview of this book

Google's Golang will be the next talk of the town, with amazing features and a powerful library. This book will gear you up for using golang by taking you through recipes that will teach you how to leverage the standard library to implement a particular solution. This will enable Go developers to take advantage of using a rock-solid standard library instead of third-party frameworks. The book begins by exploring the functionalities available for interaction between the environment and the operating system. We will explore common string operations, date/time manipulations, and numerical problems. We'll then move on to working with the database, accessing the filesystem, and performing I/O operations. From a networking perspective, we will touch on client and server-side solutions. The basics of concurrency are also covered, before we wrap up with a few tips and tricks. By the end of the book, you will have a good overview of the features of the Golang standard library and what you can achieve with them. Ultimately, you will be proficient in implementing solutions with powerful standard libraries.
Table of Contents (13 chapters)

Shutting down the application gracefully

Servers and daemons are the programs that run for a long time (typically days or even weeks). These long-running programs usually allocate resources (database connections, network sock) at the start and keep these resources as long as they exist. If such a process is killed and the shutdown is not handled properly, a resource leak could happen. To avoid that behavior, the so-called graceful shutdown should be implemented.

Graceful, in this case, means that the application catches the termination signal, if possible, and tries to clean up and release the allocated resources before it terminates. This recipe will show you how to implement the graceful shutdown.

The recipe, Handling operating system signals describes the catching of OS signals. The same approach will be used for implementing the graceful shutdown. Before the program terminates, it will clean up and carry out some other activities.

How to do it...

  1. Open the console and create the folder chapter01/recipe11.
  2. Navigate to the directory.
  3. Create the main.go file with the following content:
        package main

import (
"fmt"
"io"
"log"
"os"
"os/signal"
"syscall"
"time"
)

var writer *os.File

func main() {

// The file is opened as
// a log file to write into.
// This way we represent the resources
// allocation.
var err error
writer, err = os.OpenFile(fmt.Sprintf("test_%d.log",
time.Now().Unix()), os.O_RDWR|os.O_CREATE, os.ModePerm)
if err != nil {
panic(err)
}

// The code is running in a goroutine
// independently. So in case the program is
// terminated from outside, we need to
// let the goroutine know via the closeChan
closeChan := make(chan bool)
go func() {
for {
time.Sleep(time.Second)
select {
case <-closeChan:
log.Println("Goroutine closing")
return
default:
log.Println("Writing to log")
io.WriteString(writer, fmt.Sprintf("Logging access
%s\n", time.Now().String()))
}

}
}()

sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan,
syscall.SIGTERM,
syscall.SIGQUIT,
syscall.SIGINT)

// This is blocking read from
// sigChan where the Notify function sends
// the signal.
<-sigChan

// After the signal is received
// all the code behind the read from channel could be
// considered as a cleanup.
// CLEANUP SECTION
close(closeChan)
releaseAllResources()
fmt.Println("The application shut down gracefully")
}

func releaseAllResources() {
io.WriteString(writer, "Application releasing
all resources\n")
writer.Close()
}
  1. Run the code by executing go run main.go.
  2. Press CTRL + C to send a SIGINT signal.
  3. Wait until the Terminal output looks like this:
  1. The recipe11 folder should also contain a file called test_XXXX.log, which contains lines like this:

How it works...

The reading from a sigChan is blocking so the program keeps running until the Signal is sent through the channel. The sigChan is the channel where the Notify function sends the signals.

The main code of the program runs in a new goroutine. This way, the work continues while the main function is blocked on the sigChan. Once the signal from operation system is sent to process, the sigChan receives the signal and the code below the line where the reading from the sigChan channel is executed. This code section could be considered as the cleanup section.

Note that the step 7 terminal output contains the final log, Application releasing all resources, which is part of the cleanup section.

See also

A detailed description of how the signal catching works is in the recipe Handling operating system signals.