tears

package module
v0.0.0-...-4d12f58 Latest Latest
Warning

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

Go to latest
Published: Jun 27, 2025 License: BSD-3-Clause Imports: 5 Imported by: 0

README

tears

Go Reference

tears provides an elegant way to register cleanup functions, which are then called when the program exits. Unlike defer, it adds handling for several cleanup approaches, such as quit channels and similar mechanisms, and it offers more robustness against deadlocks and ensures proper resource teardown. The package has no dependencies outside of the standard library.

Usage

Commonly resources used throughout the lifetime of a mid-to-smallish program are set up within the main function. When the program exits, these resources need to be cleaned up. This is where tears comes in.

func main() {
    tear, down := tears.New()

    conn, _ := net.Dial("tcp", "example.com:80")
    tear(conn.Close)

    // ...
    down(ctx)
}

Over the defer statement tears has the advantage that cleanup tasks can be registered in one method and later run in another method. This is commonly the case if you separate the start and stop/close logic with methods on a struct.

type Server struct {
    tears.Cleaner
    // ...
}

func (s *Server) Start() {
    s.Tear(lis.Close)
    // ...
}

func (s *Server) Stop() {
    s.Down(context.Background())
}

Outside of calling a function directly, tears can help in closing go routines by using socalled quit-channels.

func main() {
    tear, down := tears.New()

    quit := make(chan bool)
    tear(quit)

    go func() {
        select {
        // ...
        case <-quit:
            return
        }
    }
    
    // ...
    down(context.Background())
}

Usually cleanup functions are called in a LIFO order. If you need to break out of that, tears provides a way to prioritize cleanup functions using End().

tear(conn.Close).End()

It's also possible to hook shutdown functions of another setup process into the main one.

// main.go
func main() {
    tear, down := tears.New()

    otel, shutdown := setupOtel()
    tear(shutdown)

    // ...
    down(ctx)
}

// otel.go
func setupOtel() (tears.DownFn) {
    tear, down := tears.New()

    tear(/* ... */)

    return down
}

Documentation

Overview

Package tears provides a simple way to stack functions to be run on teardown. It is useful to ensure that resources are properly released when a function returns, even if it returns early due to an error.

Index

Constants

View Source
const CleanupTimeout = 15 * time.Second

CleanupTimeout is the timeout after which a cleanup function is considered to be stuck.

Variables

This section is empty.

Functions

func New

func New() (TearFn, DownFn)

New returns a pair of tear and down functions. The tear function allows to add cleanup functions, the down function runs the cleanup.

Types

type Cleaner

type Cleaner []*Tear

Cleaner allows to register cleanup functions and run them in reverse order. it is not safe for concurrent use. A Cleaner can be embbeded into another struct to provide tear-down functionality.

func (*Cleaner) Down

func (c *Cleaner) Down(ctx context.Context) error

Down runs the cleanup functions in reverse order they have been added.

func (*Cleaner) Tear

func (c *Cleaner) Tear(v any) *Tear

Tear accepts a wide range of types that can be used as cleanup functions and types. Tear will schedule the cleanup function to be run on Down.

type DownFn

type DownFn func(context.Context) error

DownFn is a function that runs the cleanup functions in reverse order.

type Tear

type Tear struct {
	// contains filtered or unexported fields
}

func (*Tear) End

func (t *Tear) End() *Tear

End will cause the cleanup function to be run at the end of the cleanup phase. When several cleanup function are set to run at the end, they will be run in the reverse order they have been added.

type TearFn

type TearFn func(c any) *Tear

TearFn is a function that allows to add a cleanup function.

Jump to

Keyboard shortcuts

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