@@ -3,8 +3,9 @@ package show
33import (
44 "context"
55 "fmt"
6- "sort "
6+ "slices "
77 "strings"
8+ "text/tabwriter"
89
910 "github.com/cockroachdb/errors"
1011 "github.com/samber/lo"
@@ -45,29 +46,42 @@ func (c *ComponentShow) ReplicaCommand(ctx context.Context, p *ReplicaParam) (*f
4546 return nil , errors .Wrap (err , "failed to list replica info" )
4647 }
4748
49+ sessions , err := common .ListSessions (ctx , c .client , c .metaPath )
50+ if err != nil {
51+ return nil , errors .Wrap (err , "failed to list sessions" )
52+ }
53+
4854 rs := framework.NewListResult [Replicas ](replicas )
4955 rs .collections = lo .SliceToMap (collections , func (c * models.Collection ) (int64 , * models.Collection ) { return c .GetProto ().GetID (), c })
56+ rs .sessionMap = lo .SliceToMap (sessions , func (s * models.Session ) (int64 , * models.Session ) { return s .ServerID , s })
5057 return framework .NewPresetResultSet (rs , framework .NameFormat (p .Format )), nil
5158}
5259
5360type Replicas struct {
5461 framework.ListResultSet [* models.Replica ]
5562 collections map [int64 ]* models.Collection
63+ sessionMap map [int64 ]* models.Session
5664}
5765
5866func (rs * Replicas ) PrintAs (format framework.Format ) string {
5967 switch format {
6068 case framework .FormatDefault , framework .FormatPlain :
6169 sb := & strings.Builder {}
70+ tw := tabwriter .NewWriter (sb , 0 , 0 , 2 , ' ' , 0 )
6271 groups := lo .GroupBy (rs .Data , func (replica * models.Replica ) int64 { return replica .GetProto ().CollectionID })
6372 for collectionID , replicas := range groups {
64- fmt .Fprintf (sb , "CollectionID: %d\t CollectionName:%s\n " , collectionID , rs .collections [collectionID ].GetProto ().Schema .Name )
73+ collName := ""
74+ if coll , ok := rs .collections [collectionID ]; ok {
75+ collName = coll .GetProto ().Schema .Name
76+ }
77+ fmt .Fprintf (tw , "CollectionID: %d\t CollectionName: %s\n " , collectionID , collName )
6578 for _ , replica := range replicas {
66- rs .printReplica (sb , replica )
79+ rs .printReplica (tw , replica )
6780 }
68- fmt .Fprintln (sb , "================================================================================" )
69- fmt .Fprintln (sb )
81+ fmt .Fprintln (tw , "================================================================================" )
82+ fmt .Fprintln (tw )
7083 }
84+ tw .Flush ()
7185 return sb .String ()
7286 case framework .FormatJSON :
7387 return rs .printAsJSON ()
@@ -76,18 +90,26 @@ func (rs *Replicas) PrintAs(format framework.Format) string {
7690 return ""
7791}
7892
93+ type nodeInfoJSON struct {
94+ NodeID int64 `json:"node_id"`
95+ HostName string `json:"hostname"`
96+ }
97+
7998func (rs * Replicas ) printAsJSON () string {
8099 type ShardReplicaJSON struct {
81- Shard string `json:"shard"`
82- Nodes []int64 `json:"nodes"`
100+ Shard string `json:"shard"`
101+ Nodes []nodeInfoJSON `json:"nodes"`
83102 }
84103
85104 type ReplicaJSON struct {
86- ReplicaID int64 `json:"replica_id"`
87- CollectionID int64 `json:"collection_id"`
88- ResourceGroup string `json:"resource_group"`
89- Nodes []int64 `json:"nodes"`
90- ShardReplicas []ShardReplicaJSON `json:"shard_replicas,omitempty"`
105+ ReplicaID int64 `json:"replica_id"`
106+ CollectionID int64 `json:"collection_id"`
107+ ResourceGroup string `json:"resource_group"`
108+ RwNodes []nodeInfoJSON `json:"rw_nodes"`
109+ RoNodes []nodeInfoJSON `json:"ro_nodes,omitempty"`
110+ RwStreamingNodes []nodeInfoJSON `json:"rw_streaming_nodes,omitempty"`
111+ RoStreamingNodes []nodeInfoJSON `json:"ro_streaming_nodes,omitempty"`
112+ ShardReplicas []ShardReplicaJSON `json:"shard_replicas,omitempty"`
91113 }
92114
93115 type CollectionReplicasJSON struct {
@@ -120,15 +142,18 @@ func (rs *Replicas) printAsJSON() string {
120142 for shard , shardReplica := range replica .ChannelNodeInfos {
121143 shardReplicas = append (shardReplicas , ShardReplicaJSON {
122144 Shard : shard ,
123- Nodes : shardReplica .RwNodes ,
145+ Nodes : rs . toNodeInfoJSONs ( shardReplica .RwNodes ) ,
124146 })
125147 }
126148 replicaJSONs = append (replicaJSONs , ReplicaJSON {
127- ReplicaID : replica .ID ,
128- CollectionID : replica .CollectionID ,
129- ResourceGroup : replica .ResourceGroup ,
130- Nodes : replica .Nodes ,
131- ShardReplicas : shardReplicas ,
149+ ReplicaID : replica .ID ,
150+ CollectionID : replica .CollectionID ,
151+ ResourceGroup : replica .ResourceGroup ,
152+ RwNodes : rs .toNodeInfoJSONs (replica .Nodes ),
153+ RoNodes : rs .toNodeInfoJSONs (replica .RoNodes ),
154+ RwStreamingNodes : rs .toNodeInfoJSONs (replica .RwSqNodes ),
155+ RoStreamingNodes : rs .toNodeInfoJSONs (replica .RoSqNodes ),
156+ ShardReplicas : shardReplicas ,
132157 })
133158 }
134159
@@ -142,14 +167,49 @@ func (rs *Replicas) printAsJSON() string {
142167 return framework .MarshalJSON (output )
143168}
144169
145- func (rs * Replicas ) printReplica (sb * strings.Builder , r * models.Replica ) {
170+ func (rs * Replicas ) toNodeInfoJSONs (nodeIDs []int64 ) []nodeInfoJSON {
171+ if len (nodeIDs ) == 0 {
172+ return nil
173+ }
174+ result := make ([]nodeInfoJSON , 0 , len (nodeIDs ))
175+ for _ , id := range nodeIDs {
176+ result = append (result , nodeInfoJSON {NodeID : id , HostName : rs .getHostName (id )})
177+ }
178+ return result
179+ }
180+
181+ func (rs * Replicas ) getHostName (nodeID int64 ) string {
182+ if sess , ok := rs .sessionMap [nodeID ]; ok {
183+ return sess .HostName
184+ }
185+ return "NotFound"
186+ }
187+
188+ func (rs * Replicas ) printReplica (w * tabwriter.Writer , r * models.Replica ) {
146189 replica := r .GetProto ()
147- fmt .Fprintln (sb , "================================================================================" )
148- fmt .Fprintf (sb , "ReplicaID: %d \n " , replica .ID )
149- fmt .Fprintf (sb , "ResourceGroup: %s\n " , replica .ResourceGroup )
150- sort .Slice (replica .Nodes , func (i , j int ) bool { return replica .Nodes [i ] < replica .Nodes [j ] })
151- fmt .Fprintf (sb , "All Nodes:%v\n " , replica .Nodes )
190+ fmt .Fprintln (w , "================================================================================" )
191+ fmt .Fprintf (w , "ReplicaID: %d\n " , replica .ID )
192+ fmt .Fprintf (w , "ResourceGroup: %s\n " , replica .ResourceGroup )
193+ rs .printNodeList (w , "RW Query Nodes" , replica .Nodes )
194+ rs .printNodeList (w , "RO Query Nodes" , replica .RoNodes )
195+ rs .printNodeList (w , "RW Streaming Nodes" , replica .RwSqNodes )
196+ rs .printNodeList (w , "RO Streaming Nodes" , replica .RoSqNodes )
152197 for shard , shardReplica := range replica .ChannelNodeInfos {
153- fmt .Fprintf (sb , "-- Shard Replica: Shard (%s) Nodes:%v\n " , shard , shardReplica .RwNodes )
198+ fmt .Fprintf (w , "-- Shard (%s) Nodes:\n " , shard )
199+ for _ , id := range shardReplica .RwNodes {
200+ fmt .Fprintf (w , " - %d\t %s\n " , id , rs .getHostName (id ))
201+ }
202+ }
203+ }
204+
205+ func (rs * Replicas ) printNodeList (w * tabwriter.Writer , label string , nodeIDs []int64 ) {
206+ if len (nodeIDs ) == 0 {
207+ return
208+ }
209+ sorted := append ([]int64 {}, nodeIDs ... )
210+ slices .Sort (sorted )
211+ fmt .Fprintf (w , "%s (%d):\n " , label , len (sorted ))
212+ for _ , id := range sorted {
213+ fmt .Fprintf (w , " - %d\t %s\n " , id , rs .getHostName (id ))
154214 }
155215}
0 commit comments