signals

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 10, 2021 License: MIT Imports: 3 Imported by: 2

README

go-os-signals Go Report Card

Motivation

Handling signals with go is simple and awesome. But, it has limitations when you want to implement tests for what should happen when an specific signal arrives at determined time.

This library tries not to change the Go logic for signals. Neither tries to be complex. It just wraps the signal behavior into a interface that can be mocked.

Usage

Below a pretty straightforward usage of the library.

package main

import (
	"fmt"
	"syscall"

	signals "github.com/jamillosantos/go-os-signals"
)

func main() {
	l := signals.NewListener(syscall.SIGINT, syscall.SIGTERM)

	fmt.Println("Running ... [hit ctrl+c to finish]")
	sig := <-l.Receive()
	fmt.Println("Signal:", sig)
}

If you need multiple goroutines to listen to the same signal you can either use multiple Listeners or a Waiter:

package main

import (
	"fmt"
	"sync"
	"syscall"

	signals "github.com/jamillosantos/go-os-signals"
)

func main() {
	var wg sync.WaitGroup
	wg.Add(2)

	l := signals.NewWaiter(syscall.SIGINT, syscall.SIGTERM)
	go func() {
		defer wg.Done()
		l.Wait()
		fmt.Println("From GOROUTINE 1")

	}()
	go func() {
		defer wg.Done()
		l.Wait()
		fmt.Println("From GOROUTINE 2")
	}()

	fmt.Println("Running ... [hit ctrl+c to finish]")
	l.Wait()
	fmt.Println("Signal received")
	wg.Wait() // Wait goroutines to finish
}

You can find more examples at the examples folder.

Testing

For testing, the "receiving" part of the code is EXACTLY the same. But, the MockListener has one more capability: Send.

package main

import (
	"fmt"
	"syscall"
	"time"

	"github.com/jamillosantos/go-os-signals/signaltest"
)

func main() {
	l := signaltest.NewMockListener(syscall.SIGINT, syscall.SIGTERM)

	go func() {
		time.Sleep(time.Second * 1)
		l.Send(syscall.SIGINT)
	}()

	fmt.Println("Running ... [wait 1 second]")
	sig := <-l.Receive()
	fmt.Println("Signal:", sig)
}

You can find more examples at the examples folder.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Listener

type Listener interface {
	// Receive returns the receive only channel from where the signals will be
	// written to.
	Receive() <-chan os.Signal

	// Stop stops listening the signal.
	Stop()
}

Listener abstracts the behavior of a `signal.Notify` and `signal.Reset`.

The idea is to `signal.Notify` will be called at the initialization at the implementation.

func NewListener

func NewListener(signals ...os.Signal) Listener

NewListener returns the default implementation of a `Listener`.

type Waiter

type Waiter interface {
	Wait()
}

Waiter implements a locking mechanism that can be called multiples, locking multiple goroutines, and unblocks all at once when a signal arrives.

Internally it uses the Listener.Receives alongside a multiple

func NewWaiter

func NewWaiter(signals ...os.Signal) Waiter

NewWaiter creates a new Waiter initializing the listener with the given signals.

func NewWaiterWithListener

func NewWaiterWithListener(listener Listener) Waiter

NewWaiterWithListener creates a new Waiter with the given Listener.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL