chore: refactor
This commit is contained in:
61
internal/console/console.go
Normal file
61
internal/console/console.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package console
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/signal"
|
||||
"time"
|
||||
)
|
||||
|
||||
type C[A any] struct {
|
||||
io.Reader
|
||||
io.Writer
|
||||
err io.Writer
|
||||
args A
|
||||
abort func()
|
||||
cancelfns []func(context.Context) error
|
||||
}
|
||||
|
||||
func New[A any](args A) (context.Context, *C[A]) {
|
||||
ctx := context.Background()
|
||||
ctx, abort := context.WithCancel(ctx)
|
||||
ctx, stop := signal.NotifyContext(ctx, os.Interrupt)
|
||||
go func() { <-ctx.Done(); stop() }() // restore interrupt function
|
||||
|
||||
console := &C[A]{Reader: os.Stdin, Writer: os.Stdout, err: os.Stderr, args: args, abort: abort}
|
||||
return ctx, console
|
||||
}
|
||||
|
||||
func (c *C[A]) Args() A {
|
||||
return c.args
|
||||
}
|
||||
func (c *C[A]) Shutdown() error {
|
||||
fmt.Fprintln(c.err, "shutting down ", len(c.cancelfns), " cancel functions...")
|
||||
defer fmt.Fprintln(c.err, "done")
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
c.abort()
|
||||
var err error
|
||||
for _, fn := range c.cancelfns {
|
||||
err = errors.Join(err, fn(ctx))
|
||||
}
|
||||
return err
|
||||
}
|
||||
func (c *C[A]) AddCancel(fn func(context.Context) error) { c.cancelfns = append(c.cancelfns, fn) }
|
||||
|
||||
func (c *C[A]) IfFatal(err error) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
fmt.Fprintln(c.err, err)
|
||||
err = c.Shutdown()
|
||||
if err != nil {
|
||||
fmt.Fprintln(c.err, err)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
Reference in New Issue
Block a user