package assignment import ( "context" "sync" "github.com/cockroachdb/errors" "github.com/milvus-io/milvus/pkg/v2/proto/streamingpb" "github.com/milvus-io/milvus/pkg/v2/streaming/util/types" "github.com/milvus-io/milvus/pkg/v2/util/replicateutil" "github.com/milvus-io/milvus/pkg/v2/util/syncutil" "github.com/milvus-io/milvus/pkg/v2/util/typeutil" ) var ErrWatcherClosed = errors.New("watcher is closed") // newWatcher creates a new watcher. func newWatcher() *watcher { return &watcher{ cond: syncutil.NewContextCond(&sync.Mutex{}), lastVersionedAssignment: types.VersionedStreamingNodeAssignments{ Version: typeutil.VersionInt64Pair{Global: -1, Local: -1}, Assignments: make(map[int64]types.StreamingNodeAssignment), ReplicateConfigHelper: nil, }, } } // watcher is the watcher for assignment discovery. type watcher struct { cond *syncutil.ContextCond lastVersionedAssignment types.VersionedStreamingNodeAssignments } func (w *watcher) GetLatestStreamingVersion(ctx context.Context) (*streamingpb.StreamingVersion, error) { w.cond.L.Lock() for w.lastVersionedAssignment.Version.Global == -1 && w.lastVersionedAssignment.Version.Local == -1 { if err := w.cond.Wait(ctx); err != nil { return nil, err } } last := w.lastVersionedAssignment.StreamingVersion w.cond.L.Unlock() return last, nil } func (w *watcher) GetLatestDiscover(ctx context.Context) (*types.VersionedStreamingNodeAssignments, error) { w.cond.L.Lock() for w.lastVersionedAssignment.Version.Global == -1 && w.lastVersionedAssignment.Version.Local == -1 { if err := w.cond.Wait(ctx); err != nil { return nil, err } } last := w.lastVersionedAssignment w.cond.L.Unlock() return &last, nil } func (w *watcher) GetLatestReplicateConfiguration(ctx context.Context) (*replicateutil.ConfigHelper, error) { w.cond.L.Lock() for (w.lastVersionedAssignment.Version.Global == -1 && w.lastVersionedAssignment.Version.Local == -1) || w.lastVersionedAssignment.ReplicateConfigHelper == nil { if err := w.cond.Wait(ctx); err != nil { return nil, err } } last := w.lastVersionedAssignment w.cond.L.Unlock() return last.ReplicateConfigHelper, nil } // AssignmentDiscover watches the assignment discovery. func (w *watcher) AssignmentDiscover(ctx context.Context, cb func(*types.VersionedStreamingNodeAssignments) error) error { w.cond.L.Lock() for { if err := cb(&w.lastVersionedAssignment); err != nil { w.cond.L.Unlock() return err } if err := w.cond.Wait(ctx); err != nil { return err } } } // Update updates the assignment. func (w *watcher) Update(assignments types.VersionedStreamingNodeAssignments) { w.cond.LockAndBroadcast() if assignments.Version.GT(w.lastVersionedAssignment.Version) { w.lastVersionedAssignment = assignments } w.cond.L.Unlock() }