milvus/internal/rootcoord/redo.go

58 lines
1.5 KiB
Go

package rootcoord
import (
"context"
"time"
"github.com/milvus-io/milvus/internal/log"
"go.uber.org/zap"
)
type baseRedoTask struct {
syncTodoStep []Step // steps to execute synchronously
asyncTodoStep []Step // steps to execute asynchronously
}
func newBaseRedoTask() *baseRedoTask {
return &baseRedoTask{
syncTodoStep: make([]Step, 0),
asyncTodoStep: make([]Step, 0),
}
}
func (b *baseRedoTask) AddSyncStep(step Step) {
b.syncTodoStep = append(b.syncTodoStep, step)
}
func (b *baseRedoTask) AddAsyncStep(step Step) {
b.asyncTodoStep = append(b.asyncTodoStep, step)
}
func (b *baseRedoTask) redoAsyncSteps() {
// You cannot just use the ctx of task, since it will be canceled after response is returned.
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
for i := 0; i < len(b.asyncTodoStep); i++ {
todo := b.asyncTodoStep[i]
if err := todo.Execute(ctx); err != nil {
// You depend on the collection meta to do other gc.
// TODO: add ddl logger after other service can be idempotent enough, then you can do separate steps
// independently.
log.Error("failed to execute step, garbage may be generated", zap.Error(err))
return
}
}
}
func (b *baseRedoTask) Execute(ctx context.Context) error {
for i := 0; i < len(b.syncTodoStep); i++ {
todo := b.syncTodoStep[i]
if err := todo.Execute(ctx); err != nil {
log.Error("failed to execute step", zap.Error(err))
return err
}
}
go b.redoAsyncSteps()
return nil
}