| package cleanups |
| |
| import ( |
| "context" |
| |
| "github.com/docker/docker/internal/multierror" |
| ) |
| |
| type Composite struct { |
| cleanups []func(context.Context) error |
| } |
| |
| // Add adds a cleanup to be called. |
| func (c *Composite) Add(f func(context.Context) error) { |
| c.cleanups = append(c.cleanups, f) |
| } |
| |
| // Call calls all cleanups in reverse order and returns an error combining all |
| // non-nil errors. |
| func (c *Composite) Call(ctx context.Context) error { |
| err := call(ctx, c.cleanups) |
| c.cleanups = nil |
| return err |
| } |
| |
| // Release removes all cleanups, turning Call into a no-op. |
| // Caller still can call the cleanups by calling the returned function |
| // which is equivalent to calling the Call before Release was called. |
| func (c *Composite) Release() func(context.Context) error { |
| cleanups := c.cleanups |
| c.cleanups = nil |
| return func(ctx context.Context) error { |
| return call(ctx, cleanups) |
| } |
| } |
| |
| func call(ctx context.Context, cleanups []func(context.Context) error) error { |
| var errs []error |
| for idx := len(cleanups) - 1; idx >= 0; idx-- { |
| c := cleanups[idx] |
| errs = append(errs, c(ctx)) |
| } |
| return multierror.Join(errs...) |
| } |