Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Go Standard Library Cookbook

You're reading from   Go Standard Library Cookbook Over 120 specific ways to make full use of the standard library components in Golang

Arrow left icon
Product type Paperback
Published in Feb 2018
Publisher Packt
ISBN-13 9781788475273
Length 340 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Radomír Sohlich Radomír Sohlich
Author Profile Icon Radomír Sohlich
Radomír Sohlich
Arrow right icon
View More author details
Toc

Table of Contents (13) Chapters Close

Preface 1. Interacting with the Environment FREE CHAPTER 2. Strings and Things 3. Dealing with Numbers 4. Once Upon a Time 5. In and Out 6. Discovering the Filesystem 7. Connecting the Network 8. Working with Databases 9. Come to the Server Side 10. Fun with Concurrency 11. Tips and Tricks 12. Other Books You May Enjoy

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.

You have been reading a chapter from
Go Standard Library Cookbook
Published in: Feb 2018
Publisher: Packt
ISBN-13: 9781788475273
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at £16.99/month. Cancel anytime