Add Cleanupable interface

The Cleanup method is called on actors when they exit
This commit is contained in:
Sasha Koshka 2025-09-17 20:45:01 -04:00
parent e21cd9ed11
commit d34af2c4ee
3 changed files with 33 additions and 2 deletions

View File

@ -127,3 +127,10 @@ type RunShutdownable interface {
// should be shut down.
Shutdown(ctx context.Context) error
}
// Cleanupable is any object that must be cleaned up after it has stopped for
// good. Actors which implement this interface will be cleaned up after they
// are deleted from the environment.
type Cleanupable interface {
Cleanup(ctx context.Context) error
}

View File

@ -19,6 +19,7 @@ const defaultRestartInitialInterval = 8 * time.Second
const defaultRestartInitialIncrement = 8 * time.Second
const defaultRestartInitialMaximum = 1 * time.Hour
const defaultResetTimeout = 8 * time.Minute
const defaultCleanupTimeout = 1 * time.Minute
const defaultTrimInterval = 1 * time.Minute
const defaultTrimTimeout = 1 * time.Minute
const defaultShutdownTimeout = 8 * time.Minute
@ -62,6 +63,7 @@ type environment struct {
restartIntervalIncrement atomicDuration
restartIntervalMaximum atomicDuration
resetTimeout atomicDuration
cleanupTimeout atomicDuration
trimTimeout atomicDuration
shutdownTimeout atomicDuration
}
@ -238,11 +240,30 @@ func (this *environment) start(actor Actor) {
// counter will be decremented. note that this function will never increment the
// wait group counter, so start should usually be used instead.
func (this *environment) run(actor Actor) {
typ := actor.Type()
// clean up when done
defer this.group.Done()
defer func() {
this.group.Done()
this.delFromSets(actor)
if actor, ok := actor.(Cleanupable); ok {
ctx, done := context.WithTimeout(
context.Background(),
defaul(
this.timing.cleanupTimeout.Load(),
defaultCleanupTimeout))
defer done()
err := actor.Cleanup(ctx)
if err != nil {
log.Printf("XXX [%s] failed to cleanup: %v", typ, err)
if this.flags.crashOnError {
panic(fmt.Sprint(err))
}
}
}
}()
// logging
typ := actor.Type()
if this.Verb() { log.Printf("(i) [%s] running", typ) }
var stopErr error
var exited bool
@ -434,6 +455,8 @@ func (this *environment) applyConfig() error {
if err != nil { return err }
err = parseDuration("reset-timeout", &this.timing.resetTimeout)
if err != nil { return err }
err = parseDuration("cleanup-timeout", &this.timing.cleanupTimeout)
if err != nil { return err }
err = parseDuration("trim-timeout", &this.timing.trimTimeout)
if err != nil { return err }
err = parseDuration("shutdown-timeout", &this.timing.shutdownTimeout)

View File

@ -279,6 +279,7 @@ func (this *environment) phase70_5Trimming() bool {
}
func (this *environment) phase80Shutdown() bool {
logActors(All())
ctx, done := context.WithTimeout(
context.Background(),
defaul(this.timing.shutdownTimeout.Load(), defaultShutdownTimeout))