1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-02-03 13:11:48 +02:00
Carlos Alexandro Becker ed14fe7b99
fix: move code to new pkg
so we can better cover it with tests
2017-12-30 00:55:44 -02:00

54 lines
1.3 KiB
Go

// Package handler provides a way of having a task that is context-aware and
// that also deals with interrup and term signals.
// It was externalized mostly because it would be easier to test it this way.
// The name is not ideal but I couldn't think in a better one.
package handler
import (
"context"
"fmt"
"os"
"os/signal"
"syscall"
)
// Task is function that can be executed by a Handler
type Task func() error
// Handler is the task handler
type Handler struct {
signals chan os.Signal
errs chan error
}
// New returns a new handler with its internals setup.
func New() *Handler {
return &Handler{
signals: make(chan os.Signal, 1),
errs: make(chan error, 1),
}
}
// Run executes a given task with a given context, dealing with its timeouts,
// cancels and SIGTERM and SIGINT signals.
// It will return an error if the context is canceled, if deadline exceeds,
// if a SIGTERM or SIGINT is received and of course if the task itself fails.
func (h *Handler) Run(ctx context.Context, task Task) error {
go func() {
if err := task(); err != nil {
h.errs <- err
return
}
h.errs <- nil
}()
signal.Notify(h.signals, syscall.SIGINT, syscall.SIGTERM)
select {
case err := <-h.errs:
return err
case <-ctx.Done():
return ctx.Err()
case sig := <-h.signals:
return fmt.Errorf("received: %s", sig)
}
}