draincloud-core/internal/closer/closer.go

51 lines
875 B
Go

package closer
import (
"context"
"errors"
"fmt"
"sync/atomic"
"git.optclblast.xyz/draincloud/draincloud-core/internal/logger"
)
var globalCloser *Closer = &Closer{
closeFns: make([]func() error, 0),
}
type Closer struct {
_lock atomic.Bool
closeFns []func() error
}
func (c *Closer) Add(fn func() error) {
if c._lock.Load() {
return
}
c.closeFns = append(c.closeFns, fn)
}
func (c *Closer) Close() error {
if !c._lock.CompareAndSwap(false, true) {
return fmt.Errorf("already closed")
}
var commonErr error
for _, fn := range c.closeFns {
if err := fn(); err != nil {
logger.Error(context.Background(), "[closer][Close] error at close func call", logger.Err(err))
commonErr = errors.Join(commonErr, err)
}
}
return commonErr
}
func Add(fn func() error) {
globalCloser.Add(fn)
}
func Close() error {
return globalCloser.Close()
}