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)

Handling operating system signals

Signals are the elementary way the operating systems communicate with the running process. Two of the most usual signals are called SIGINT and SIGTERM. These cause the program to terminate.

There are also signals such as SIGHUP. SIGHUP indicates that the terminal which called the process was closed and, for example, the program could decide to move to the background.

Go provides a way of handling the behavior in case the application received the signal. This recipe will provide an example of implementing the handling.

How to do it...

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

import (
"fmt"
"os"
"os/signal"
"syscall"
)

func main() {

// Create the channel where the received
// signal would be sent. The Notify
// will not block when the signal
// is sent and the channel is not ready.
// So it is better to
// create buffered channel.
sChan := make(chan os.Signal, 1)

// Notify will catch the
// given signals and send
// the os.Signal value
// through the sChan.
// If no signal specified in
// argument, all signals are matched.
signal.Notify(sChan,
syscall.SIGHUP,
syscall.SIGINT,
syscall.SIGTERM,
syscall.SIGQUIT)

// Create channel to wait till the
// signal is handled.
exitChan := make(chan int)
go func() {
signal := <-sChan
switch signal {
case syscall.SIGHUP:
fmt.Println("The calling terminal has been closed")
exitChan <- 0

case syscall.SIGINT:
fmt.Println("The process has been interrupted by CTRL+C")
exitChan <- 1

case syscall.SIGTERM:
fmt.Println("kill SIGTERM was executed for process")
exitChan <- 1

case syscall.SIGQUIT:
fmt.Println("kill SIGQUIT was executed for process")
exitChan <- 1
}
}()

code := <-exitChan
os.Exit(code)
}
  1. Run the code by executing go run main.go.
  2. Send the SIGINT signal to the application by pressing CTRL + C.
  3. See the output:

How it works...

In an application, where the resources are acquired, a resource leak could happen in the case of an instant termination. It is better to handle the signals and take some necessary steps to release the resources. The preceding code shows the concept of how to do that.

The Notify function from the signal package would be the one that helps us to handle the received signals.

If no signal is specified as an argument in a Notify function, the function will catch all possible signals.

Note that the Notify function of the signal package is communicating with the goroutine by the sChan channel. Notify then catches the defined signals and sends these to goroutine to be handled. Finally, exitChan is used to resolve the exit code of the process.

The important information is that the Notify function will not block the signal if the assigned channel is not ready. This way the signal could be missed. To avoid missing the signal, it is better to create the buffered channel.

Note that the SIGKILL and SIGSTOP signals may not be caught by the Notify function, thus it is not possible to handle these.