// Licensed to the LF AI & Data foundation under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package proxy import ( "context" "strconv" "go.opentelemetry.io/otel" "go.uber.org/zap" "github.com/milvus-io/milvus-proto/go-api/v2/commonpb" "github.com/milvus-io/milvus-proto/go-api/v2/milvuspb" "github.com/milvus-io/milvus/pkg/v2/log" "github.com/milvus-io/milvus/pkg/v2/metrics" "github.com/milvus-io/milvus/pkg/v2/util/merr" "github.com/milvus-io/milvus/pkg/v2/util/paramtable" "github.com/milvus-io/milvus/pkg/v2/util/timerecord" "github.com/milvus-io/milvus/pkg/v2/util/typeutil" ) func (node *Proxy) CreateSnapshot(ctx context.Context, req *milvuspb.CreateSnapshotRequest) (*commonpb.Status, error) { ctx, sp := otel.Tracer(typeutil.ProxyRole).Start(ctx, "Proxy-CreateSnapshot") defer sp.End() log := log.Ctx(ctx).With( zap.String("snapshotName", req.GetName()), zap.String("collectionName", req.GetCollectionName()), ) method := "CreateSnapshot" tr := timerecord.NewTimeRecorder(method) log.Info(rpcReceived(method)) metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.TotalLabel, req.GetDbName(), req.GetCollectionName()).Inc() t := &createSnapshotTask{ req: req, ctx: ctx, Condition: NewTaskCondition(ctx), mixCoord: node.mixCoord, } err := node.sched.ddQueue.Enqueue(t) if err != nil { metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.AbandonLabel, req.GetDbName(), req.GetCollectionName()).Inc() log.Warn("CreateSnapshot failed to Enqueue", zap.Error(err)) return merr.Status(err), nil } if err := t.WaitToFinish(); err != nil { metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.FailLabel, req.GetDbName(), req.GetCollectionName()).Inc() log.Warn("CreateSnapshot failed to WaitToFinish", zap.Error(err)) return merr.Status(err), nil } metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.SuccessLabel, req.GetDbName(), req.GetCollectionName()).Inc() metrics.ProxyReqLatency.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method).Observe(float64(tr.ElapseSpan().Milliseconds())) return t.result, nil } func (node *Proxy) DropSnapshot(ctx context.Context, req *milvuspb.DropSnapshotRequest) (*commonpb.Status, error) { ctx, sp := otel.Tracer(typeutil.ProxyRole).Start(ctx, "Proxy-DropSnapshot") defer sp.End() log := log.Ctx(ctx).With( zap.String("snapshotName", req.GetName()), ) method := "DropSnapshot" tr := timerecord.NewTimeRecorder(method) log.Info(rpcReceived(method)) metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.TotalLabel, "", "").Inc() t := &dropSnapshotTask{ req: req, ctx: ctx, Condition: NewTaskCondition(ctx), mixCoord: node.mixCoord, } err := node.sched.ddQueue.Enqueue(t) if err != nil { metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.AbandonLabel, "", "").Inc() log.Warn("DropSnapshot failed to Enqueue", zap.Error(err)) return merr.Status(err), nil } if err := t.WaitToFinish(); err != nil { metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.FailLabel, "", "").Inc() log.Warn("DropSnapshot failed to WaitToFinish", zap.Error(err)) return merr.Status(err), nil } metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.SuccessLabel, "", "").Inc() metrics.ProxyReqLatency.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method).Observe(float64(tr.ElapseSpan().Milliseconds())) return t.result, nil } func (node *Proxy) DescribeSnapshot(ctx context.Context, req *milvuspb.DescribeSnapshotRequest) (*milvuspb.DescribeSnapshotResponse, error) { ctx, sp := otel.Tracer(typeutil.ProxyRole).Start(ctx, "Proxy-DescribeSnapshot") defer sp.End() log := log.Ctx(ctx).With( zap.String("snapshotName", req.GetName()), ) method := "DescribeSnapshot" tr := timerecord.NewTimeRecorder(method) log.Info(rpcReceived(method)) metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.TotalLabel, "", "").Inc() t := &describeSnapshotTask{ req: req, ctx: ctx, Condition: NewTaskCondition(ctx), mixCoord: node.mixCoord, } err := node.sched.ddQueue.Enqueue(t) if err != nil { metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.AbandonLabel, "", "").Inc() log.Warn("DescribeSnapshot failed to Enqueue", zap.Error(err)) return &milvuspb.DescribeSnapshotResponse{ Status: merr.Status(err), }, nil } if err := t.WaitToFinish(); err != nil { metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.FailLabel, "", "").Inc() log.Warn("DescribeSnapshot failed to WaitToFinish", zap.Error(err)) return &milvuspb.DescribeSnapshotResponse{ Status: merr.Status(err), }, nil } metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.SuccessLabel, "", "").Inc() metrics.ProxyReqLatency.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method).Observe(float64(tr.ElapseSpan().Milliseconds())) return t.result, nil } func (node *Proxy) ListSnapshots(ctx context.Context, req *milvuspb.ListSnapshotsRequest) (*milvuspb.ListSnapshotsResponse, error) { ctx, sp := otel.Tracer(typeutil.ProxyRole).Start(ctx, "Proxy-ListSnapshots") defer sp.End() log := log.Ctx(ctx).With( zap.String("collectionName", req.GetCollectionName())) method := "ListSnapshots" tr := timerecord.NewTimeRecorder(method) log.Info(rpcReceived(method)) metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.TotalLabel, req.GetCollectionName(), "").Inc() t := &listSnapshotsTask{ req: req, ctx: ctx, Condition: NewTaskCondition(ctx), mixCoord: node.mixCoord, } err := node.sched.ddQueue.Enqueue(t) if err != nil { metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.AbandonLabel, req.GetCollectionName(), "").Inc() log.Warn("ListSnapshots failed to Enqueue", zap.Error(err)) return &milvuspb.ListSnapshotsResponse{ Status: merr.Status(err), }, nil } if err := t.WaitToFinish(); err != nil { metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.FailLabel, req.GetCollectionName(), "").Inc() log.Warn("ListSnapshots failed to WaitToFinish", zap.Error(err)) return &milvuspb.ListSnapshotsResponse{ Status: merr.Status(err), }, nil } metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.SuccessLabel, req.GetCollectionName(), "").Inc() metrics.ProxyReqLatency.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method).Observe(float64(tr.ElapseSpan().Milliseconds())) return t.result, nil } func (node *Proxy) RestoreSnapshot(ctx context.Context, req *milvuspb.RestoreSnapshotRequest) (*milvuspb.RestoreSnapshotResponse, error) { ctx, sp := otel.Tracer(typeutil.ProxyRole).Start(ctx, "Proxy-RestoreSnapshot") defer sp.End() log := log.Ctx(ctx).With( zap.String("snapshotName", req.GetName()), ) method := "RestoreSnapshot" tr := timerecord.NewTimeRecorder(method) log.Info(rpcReceived(method)) metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.TotalLabel, "", "").Inc() t := &restoreSnapshotTask{ req: req, ctx: ctx, Condition: NewTaskCondition(ctx), mixCoord: node.mixCoord, } err := node.sched.ddQueue.Enqueue(t) if err != nil { metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.AbandonLabel, "", "").Inc() log.Warn("RestoreSnapshot failed to Enqueue", zap.Error(err)) return &milvuspb.RestoreSnapshotResponse{Status: merr.Status(err)}, nil } if err := t.WaitToFinish(); err != nil { metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.FailLabel, "", "").Inc() log.Warn("RestoreSnapshot failed to WaitToFinish", zap.Error(err)) return &milvuspb.RestoreSnapshotResponse{Status: merr.Status(err)}, nil } metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.SuccessLabel, "", "").Inc() metrics.ProxyReqLatency.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method).Observe(float64(tr.ElapseSpan().Milliseconds())) return t.result, nil } func (node *Proxy) GetRestoreSnapshotState(ctx context.Context, req *milvuspb.GetRestoreSnapshotStateRequest) (*milvuspb.GetRestoreSnapshotStateResponse, error) { ctx, sp := otel.Tracer(typeutil.ProxyRole).Start(ctx, "Proxy-GetRestoreSnapshotState") defer sp.End() log := log.Ctx(ctx).With( zap.Int64("jobID", req.GetJobId()), ) method := "GetRestoreSnapshotState" tr := timerecord.NewTimeRecorder(method) log.Info(rpcReceived(method)) metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.TotalLabel, "", "").Inc() t := &getRestoreSnapshotStateTask{ req: req, ctx: ctx, Condition: NewTaskCondition(ctx), mixCoord: node.mixCoord, } err := node.sched.ddQueue.Enqueue(t) if err != nil { metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.AbandonLabel, "", "").Inc() log.Warn("GetRestoreSnapshotState failed to Enqueue", zap.Error(err)) return &milvuspb.GetRestoreSnapshotStateResponse{ Status: merr.Status(err), }, nil } if err := t.WaitToFinish(); err != nil { metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.FailLabel, "", "").Inc() log.Warn("GetRestoreSnapshotState failed to WaitToFinish", zap.Error(err)) return &milvuspb.GetRestoreSnapshotStateResponse{ Status: merr.Status(err), }, nil } metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.SuccessLabel, "", "").Inc() metrics.ProxyReqLatency.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method).Observe(float64(tr.ElapseSpan().Milliseconds())) return t.result, nil } func (node *Proxy) ListRestoreSnapshotJobs(ctx context.Context, req *milvuspb.ListRestoreSnapshotJobsRequest) (*milvuspb.ListRestoreSnapshotJobsResponse, error) { ctx, sp := otel.Tracer(typeutil.ProxyRole).Start(ctx, "Proxy-ListRestoreSnapshotJobs") defer sp.End() log := log.Ctx(ctx).With( zap.String("collectionName", req.GetCollectionName()), ) method := "ListRestoreSnapshotJobs" tr := timerecord.NewTimeRecorder(method) log.Info(rpcReceived(method)) metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.TotalLabel, req.GetCollectionName(), "").Inc() t := &listRestoreSnapshotJobsTask{ req: req, ctx: ctx, Condition: NewTaskCondition(ctx), mixCoord: node.mixCoord, } err := node.sched.ddQueue.Enqueue(t) if err != nil { metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.AbandonLabel, req.GetCollectionName(), "").Inc() log.Warn("ListRestoreSnapshotJobs failed to Enqueue", zap.Error(err)) return &milvuspb.ListRestoreSnapshotJobsResponse{ Status: merr.Status(err), }, nil } if err := t.WaitToFinish(); err != nil { metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.FailLabel, req.GetCollectionName(), "").Inc() log.Warn("ListRestoreSnapshotJobs failed to WaitToFinish", zap.Error(err)) return &milvuspb.ListRestoreSnapshotJobsResponse{ Status: merr.Status(err), }, nil } metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method, metrics.SuccessLabel, req.GetCollectionName(), "").Inc() metrics.ProxyReqLatency.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method).Observe(float64(tr.ElapseSpan().Milliseconds())) return t.result, nil }