stager

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Feb 14, 2020 License: Apache-2.0 Imports: 2 Imported by: 27

README

Stager

Stager is a library to help write code where you are in control of start and shutdown of concurrent operations. I.e. you know when goroutines start and stop and in which order.

A runnable example:

package main

import (
	"context"
	"log"
	"time"

	"github.com/ash2k/stager"
)

func main() {
	defer log.Print("Exiting main")
	st := stager.New()
	defer st.Shutdown()

	ball := make(chan struct{})
	p1 := ping{
		ball: ball,
	}
	s := st.NextStage()
	s.StartWithContext(p1.run)

	p2 := pong{
		ball: ball,
	}
	s = st.NextStage()
	s.StartWithContext(p2.run)

	time.Sleep(5 * time.Second)
}

type ping struct {
	ball chan struct{}
}

func (p *ping) run(ctx context.Context) {
	log.Print("Starting ping")
	defer log.Print("Shutting down ping")
	for {
		select {
		case <-ctx.Done():
			return
		case <-p.ball:
		}
		select {
		case <-ctx.Done():
			return
		case <-time.After(time.Second):
		}
		log.Print("ping")
		select {
		case <-ctx.Done():
			return
		case p.ball <- struct{}{}:
		}
	}
}

type pong struct {
	ball chan struct{}
}

func (p *pong) run(ctx context.Context) {
	log.Print("Starting pong")
	defer time.Sleep(time.Second)
	defer log.Print("Shutting down pong - sleeping 1 second")
	for {
		select {
		case <-ctx.Done():
			return
		case p.ball <- struct{}{}:
		}
		select {
		case <-ctx.Done():
			return
		case <-p.ball:
		}
		select {
		case <-ctx.Done():
			return
		case <-time.After(time.Second):
		}
		log.Print("pong")
	}
}

Output:

2017/06/20 13:34:33 Starting pong
2017/06/20 13:34:33 Starting ping
2017/06/20 13:34:34 ping
2017/06/20 13:34:35 pong
2017/06/20 13:34:36 ping
2017/06/20 13:34:37 pong
2017/06/20 13:34:38 Shutting down pong - sleeping 1 second
2017/06/20 13:34:38 ping
2017/06/20 13:34:39 Shutting down ping
2017/06/20 13:34:39 Exiting main

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Stage

type Stage interface {
	// Start starts f in a new goroutine attached to the Stage.
	Start(func())
	// StartWithChannel starts f in a new goroutine attached to the Stage.
	// Stage context's Done() channel is passed to f as an argument. f should stop when it is available.
	StartWithChannel(func(stopCh <-chan struct{}))
	// StartWithContext starts f in a new goroutine attached to the Stage.
	// Stage context is passed to f as an argument. f should stop when context's Done() channel is available.
	StartWithContext(func(context.Context))
}

type Stager

type Stager interface {
	// NextStageWithContext adds a new stage to the Stager.
	NextStage() Stage
	// NextStageWithContext adds a new stage to the Stager. Provided ctxParent is used as the parent context for the
	// Stage's context.
	NextStageWithContext(ctxParent context.Context) Stage
	// Shutdown iterates Stages in reverse order, cancelling their context and waiting for all started goroutines
	// to finish for each Stage.
	Shutdown()
}

func New

func New() Stager

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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