draincloud-core/internal/closer/closer.go

51 lines
875 B
Go
Raw Normal View History

2024-09-27 22:37:58 +00:00
package closer
import (
"context"
"errors"
2025-01-10 23:09:37 +00:00
"fmt"
"sync/atomic"
2024-09-27 22:37:58 +00:00
2024-10-10 21:36:51 +00:00
"git.optclblast.xyz/draincloud/draincloud-core/internal/logger"
2024-09-27 22:37:58 +00:00
)
var globalCloser *Closer = &Closer{
closeFns: make([]func() error, 0),
}
type Closer struct {
2025-01-10 23:09:37 +00:00
_lock atomic.Bool
2024-09-27 22:37:58 +00:00
closeFns []func() error
}
func (c *Closer) Add(fn func() error) {
2025-01-10 23:09:37 +00:00
if c._lock.Load() {
return
}
2024-09-27 22:37:58 +00:00
c.closeFns = append(c.closeFns, fn)
}
func (c *Closer) Close() error {
2025-01-10 23:09:37 +00:00
if !c._lock.CompareAndSwap(false, true) {
return fmt.Errorf("already closed")
}
2024-09-27 22:37:58 +00:00
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()
}