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