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()
|
|
|
|
}
|