All Projects → pseidemann → Finish

pseidemann / Finish

Licence: bsd-3-clause
A non-intrusive library adding a graceful shutdown to Go HTTP servers.

Programming Languages

go
31211 projects - #10 most used programming language
golang
3204 projects

Labels

Projects that are alternatives of or similar to Finish

Esp32 Mpu Driver
ESP32 full library for all MPU6000 MPU6050 MPU6500 MPU9150 MPU9250 with SPI and I2C support and more.
Stars: ✭ 111 (-3.48%)
Mutual labels:  library
Overrideit Sketchplugin
Overrideit is sketch plugin that allow designers to search in overridelist and overrides dropdowns, and with many other features.
Stars: ✭ 113 (-1.74%)
Mutual labels:  library
Indicators
Activity Indicators for Modern C++
Stars: ✭ 1,838 (+1498.26%)
Mutual labels:  library
Battery.js
A tiny wrapper for the HTML5 Battery Status API.
Stars: ✭ 111 (-3.48%)
Mutual labels:  library
Bloc.js
A predictable state management library that helps implement the BLoC design pattern in JavaScript
Stars: ✭ 111 (-3.48%)
Mutual labels:  library
Php Cli
PHP library to build command line tools
Stars: ✭ 113 (-1.74%)
Mutual labels:  library
Bokkypoobahsdatetimelibrary
Gas-Efficient Solidity DateTime Library
Stars: ✭ 111 (-3.48%)
Mutual labels:  library
Netius
Readable, simple and fast asynchronous non-blocking network apps
Stars: ✭ 114 (-0.87%)
Mutual labels:  library
Redis Store
Namespaced Rack::Session, Rack::Cache, I18n and cache Redis stores for Ruby web frameworks
Stars: ✭ 1,466 (+1174.78%)
Mutual labels:  library
Ndef Tools For Android
NDEF Tools for Android
Stars: ✭ 113 (-1.74%)
Mutual labels:  library
Androidaudiorecorder
A fancy audio recorder lib for Android. Supports WAV format at 48kHz.
Stars: ✭ 1,524 (+1225.22%)
Mutual labels:  library
Deepcopy.js
deep copy data
Stars: ✭ 112 (-2.61%)
Mutual labels:  library
Hypre
See https://github.com/hypre-space/hypre for the development repository and releases. This repo will eventually be removed.
Stars: ✭ 113 (-1.74%)
Mutual labels:  library
Inapppy
Python In-app purchase validator for Apple AppStore and GooglePlay.
Stars: ✭ 110 (-4.35%)
Mutual labels:  library
Styled Typography
Typograpy components for react and styled-components
Stars: ✭ 113 (-1.74%)
Mutual labels:  library
Lift
constexpr C++17 library for simplifying higher order functions in application code
Stars: ✭ 111 (-3.48%)
Mutual labels:  library
Petal
A modern, light CSS UI framework by Shakr
Stars: ✭ 113 (-1.74%)
Mutual labels:  library
Aura.ui
A Library with a lot of Controls for AvaloniaUI
Stars: ✭ 114 (-0.87%)
Mutual labels:  library
Liquidrefreshlayout
Liquid Refresh Layout is a simple SwipeToRefresh library that helps you easily integrate SwipeToRefresh and performs simple clean liquid animation
Stars: ✭ 114 (-0.87%)
Mutual labels:  library
Tls Channel
A Java library that implements a ByteChannel interface over SSLEngine, enabling easy-to-use (socket-like) TLS for Java applications.
Stars: ✭ 113 (-1.74%)
Mutual labels:  library

finish

GoDoc Go Report Card Build Status

A non-intrusive package adding a graceful shutdown to Go's HTTP server by utilizing http.Server's built-in Shutdown() method.

Quick Start

Assume the following code in a file called simple.go:

package main

import (
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/pseidemann/finish"
)

func main() {
	http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
		time.Sleep(5 * time.Second)
		fmt.Fprintln(w, "world")
	})

	srv := &http.Server{Addr: "localhost:8080"}

	fin := finish.New()
	fin.Add(srv)

	go func() {
		err := srv.ListenAndServe()
		if err != http.ErrServerClosed {
			log.Fatal(err)
		}
	}()

	fin.Wait()
}

Now execute that file:

$ go run simple.go

Do a HTTP GET request:

$ curl localhost:8080/hello

This will print "world" after 5 seconds.

When the server is terminated with pressing Ctrl+C or kill, while /hello is loading, finish will wait until the request was handled, before the server gets killed.

The output will look like this:

2038/01/19 03:14:08 finish: shutdown signal received
2038/01/19 03:14:08 finish: shutting down server ...
2038/01/19 03:14:11 finish: server closed

Customization

Change Timeout

How to change the default timeout of 10 seconds.

package main

import (
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/pseidemann/finish"
)

func main() {
	http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
		time.Sleep(5 * time.Second)
		fmt.Fprintln(w, "world")
	})

	srv := &http.Server{Addr: "localhost:8080"}

	fin := &finish.Finisher{Timeout: 30 * time.Second}
	fin.Add(srv)

	go func() {
		err := srv.ListenAndServe()
		if err != http.ErrServerClosed {
			log.Fatal(err)
		}
	}()

	fin.Wait()
}

In this example the timeout is set to 30 seconds.

Change Logger

How to change the default logger.

package main

import (
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/pseidemann/finish"
	"github.com/sirupsen/logrus"
)

func main() {
	http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
		time.Sleep(5 * time.Second)
		fmt.Fprintln(w, "world")
	})

	srv := &http.Server{Addr: "localhost:8080"}

	fin := &finish.Finisher{Log: logrus.StandardLogger()}
	fin.Add(srv)

	go func() {
		err := srv.ListenAndServe()
		if err != http.ErrServerClosed {
			log.Fatal(err)
		}
	}()

	fin.Wait()
}

In this example, logrus is configured for logging.

Change Signals

How to change the default signals (SIGINT, SIGTERM) which will initiate the shutdown.

package main

import (
	"fmt"
	"log"
	"net/http"
	"syscall"
	"time"

	"github.com/pseidemann/finish"
)

func main() {
	http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
		time.Sleep(5 * time.Second)
		fmt.Fprintln(w, "world")
	})

	srv := &http.Server{Addr: "localhost:8080"}

	fin := &finish.Finisher{Signals: append(finish.DefaultSignals, syscall.SIGHUP)}
	fin.Add(srv)

	go func() {
		err := srv.ListenAndServe()
		if err != http.ErrServerClosed {
			log.Fatal(err)
		}
	}()

	fin.Wait()
}

In this example, finish will not only catch the default signals SIGINT and SIGTERM but also the signal SIGHUP.

Full Example

This example uses a custom router httprouter, a different timeout, a custom logger logrus, custom signals, options for Add() and multiple servers.

package main

import (
	"fmt"
	"log"
	"net/http"
	"syscall"
	"time"

	"github.com/julienschmidt/httprouter"
	"github.com/pseidemann/finish"
	"github.com/sirupsen/logrus"
)

func main() {
	routerPub := httprouter.New()
	routerPub.HandlerFunc("GET", "/hello", func(w http.ResponseWriter, r *http.Request) {
		time.Sleep(5 * time.Second)
		fmt.Fprintln(w, "world")
	})

	routerInt := httprouter.New()
	routerInt.HandlerFunc("GET", "/status", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "ok")
	})

	srvPub := &http.Server{Addr: "localhost:8080", Handler: routerPub}
	srvInt := &http.Server{Addr: "localhost:3000", Handler: routerInt}

	fin := &finish.Finisher{
		Timeout: 30 * time.Second,
		Log:     logrus.StandardLogger(),
		Signals: append(finish.DefaultSignals, syscall.SIGHUP),
	}
	fin.Add(srvPub, finish.WithName("public server"))
	fin.Add(srvInt, finish.WithName("internal server"), finish.WithTimeout(5*time.Second))

	go func() {
		logrus.Infof("starting public server at %s", srvPub.Addr)
		err := srvPub.ListenAndServe()
		if err != http.ErrServerClosed {
			log.Fatal(err)
		}
	}()

	go func() {
		logrus.Infof("starting internal server at %s", srvInt.Addr)
		err := srvInt.ListenAndServe()
		if err != http.ErrServerClosed {
			log.Fatal(err)
		}
	}()

	fin.Wait()
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].