mirror of
https://github.com/milvus-io/milvus.git
synced 2026-07-21 10:15:43 +00:00
enhance: add DumpMessages to the Go SDK client (#50343)
issue: #47598 ## Summary The `DumpMessages` streaming RPC (added in #47599 for data salvage) is exposed by the proto and the low-level `milvuspb` stub, but the high-level Go SDK client (`client/milvusclient`) had **no wrapper** — unlike the sibling replicate APIs (`UpdateReplicateConfiguration`, `GetReplicateConfiguration`, `GetReplicateInfo`, `CreateReplicateStream`) that already live in `replicate.go`. This adds `Client.DumpMessages`, mirroring `CreateReplicateStream`: it returns the server-streaming client whose `Recv()` yields `DumpMessagesResponse` frames (each carrying either an error status or a non-system message). For reference, the Python SDK already exposes this API in milvus-io/pymilvus#3573. ## Changes - `client/milvusclient/replicate.go`: add `Client.DumpMessages(ctx, req, opts...) (milvuspb.MilvusService_DumpMessagesClient, error)`. - `client/milvusclient/replicate_example_test.go`: add `ExampleClient_DumpMessages` showing the salvage flow (`GetReplicateInfo` → salvage checkpoint → `DumpMessages` → iterate to `io.EOF`). ## Test Plan - [x] `go build ./milvusclient/` and `go vet ./milvusclient/` pass - [x] `go test ./milvusclient/ -run TestReplicate` passes - [x] Example compiles (built as part of the package test binary) - [x] gofmt clean Signed-off-by: bigsheeper <yihao.dai@zilliz.com>
This commit is contained in:
@@ -62,3 +62,27 @@ func (c *Client) CreateReplicateStream(ctx context.Context, opts ...grpc.CallOpt
|
||||
})
|
||||
return streamClient, err
|
||||
}
|
||||
|
||||
// DumpMessages streams messages from a WAL range for data salvage.
|
||||
// It is typically used after a force failover: callers obtain the salvage
|
||||
// checkpoint from GetReplicateInfo and pass its message id as the request's
|
||||
// StartMessageId to recover messages that were not yet synchronized.
|
||||
//
|
||||
// The returned stream yields DumpMessagesResponse frames; each frame carries
|
||||
// either an error status or a non-system message. Iterate with stream.Recv()
|
||||
// until io.EOF.
|
||||
func (c *Client) DumpMessages(ctx context.Context, req *milvuspb.DumpMessagesRequest, opts ...grpc.CallOption) (milvuspb.MilvusService_DumpMessagesClient, error) {
|
||||
var streamClient milvuspb.MilvusService_DumpMessagesClient
|
||||
err := c.callService(func(milvusService milvuspb.MilvusServiceClient) error {
|
||||
var err error
|
||||
streamClient, err = milvusService.DumpMessages(ctx, req, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if streamClient == nil {
|
||||
return errors.New("stream client is nil")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return streamClient, err
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package milvusclient_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"log"
|
||||
|
||||
"github.com/milvus-io/milvus-proto/go-api/v3/milvuspb"
|
||||
@@ -118,3 +119,60 @@ func ExampleClient_CreateReplicateStream() {
|
||||
// Here you can continue to use the stream for data transmission
|
||||
// For example: stream.Send(&milvuspb.ReplicateMessage{...})
|
||||
}
|
||||
|
||||
func ExampleClient_DumpMessages() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
cli, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
|
||||
Address: exampleMilvusAddr,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// After a force failover, use GetReplicateInfo to obtain the salvage
|
||||
// checkpoint, then dump the unsynchronized messages from that position.
|
||||
info, err := cli.GetReplicateInfo(ctx, &milvuspb.GetReplicateInfoRequest{
|
||||
SourceClusterId: "source-cluster",
|
||||
TargetPchannel: "source-channel-dml_0",
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("Failed to get replicate information: %v", err)
|
||||
return
|
||||
}
|
||||
ckpt := info.GetSalvageCheckpoint()
|
||||
if ckpt == nil {
|
||||
log.Println("No salvage checkpoint available")
|
||||
return
|
||||
}
|
||||
|
||||
stream, err := cli.DumpMessages(ctx, &milvuspb.DumpMessagesRequest{
|
||||
Pchannel: ckpt.GetPchannel(),
|
||||
StartMessageId: ckpt.GetMessageId(),
|
||||
StartTimetick: ckpt.GetTimeTick(),
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("Failed to dump messages: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
resp, err := stream.Recv()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("Failed to receive dumped message: %v", err)
|
||||
return
|
||||
}
|
||||
if msg := resp.GetMessage(); msg != nil {
|
||||
log.Printf("Dumped message: %v", msg.GetId())
|
||||
} else if status := resp.GetStatus(); status != nil {
|
||||
log.Printf("Received error status: %v", status)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
log.Println("Dump messages completed")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user