func (ms *maintenanceServer) Snapshot(sr *pb.SnapshotRequest, srv pb.Maintenance_SnapshotServer) error { snap := ms.bg.Backend().Snapshot() pr, pw := io.Pipe() defer pr.Close() go func() { snap.WriteTo(pw) if err := snap.Close(); err != nil { plog.Errorf("error closing snapshot (%v)", err) } pw.Close() }() br := int64(0) buf := make([]byte, 32*1024) sz := snap.Size() for br < sz { n, err := io.ReadFull(pr, buf) if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF { return togRPCError(err) } br += int64(n) resp := &pb.SnapshotResponse{ RemainingBytes: uint64(sz - br), Blob: buf[:n], } if err = srv.Send(resp); err != nil { return togRPCError(err) } } return nil }
func (mp *maintenanceProxy) Snapshot(sr *pb.SnapshotRequest, stream pb.Maintenance_SnapshotServer) error { conn := mp.client.ActiveConnection() ctx, cancel := context.WithCancel(stream.Context()) defer cancel() sc, err := pb.NewMaintenanceClient(conn).Snapshot(ctx, sr) if err != nil { return err } for { rr, err := sc.Recv() if err != nil { return err } err = stream.Send(rr) if err != nil { return err } } }