Skip to content

Commit 8b56ef7

Browse files
committed
Structure shard status as tree
1 parent f9c3dd0 commit 8b56ef7

File tree

7 files changed

+176
-28
lines changed

7 files changed

+176
-28
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2018 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
// Author Ewout Prangsma
21+
//
22+
23+
package v1alpha
24+
25+
// CollectionStatus contains the status of a single collection.
26+
type CollectionStatus struct {
27+
// Name of the collection
28+
Name string `json:"name"`
29+
// Replication status per shard.
30+
// The list is ordered by shard index (0..noShards-1)
31+
Shards []ShardStatus `json:"shards,omitempty"`
32+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2018 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
// Author Ewout Prangsma
21+
//
22+
23+
package v1alpha
24+
25+
// DatabaseStatus contains the status of a single database.
26+
type DatabaseStatus struct {
27+
// Name of the database
28+
Name string `json:"name"`
29+
// Collections holds the replication status of each collection in the database.
30+
// List is ordered by name of the collection.
31+
Collections []CollectionStatus `json:"collections,omitempty"`
32+
}

pkg/apis/replication/v1alpha/endpoint_status.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,7 @@ package v1alpha
2424

2525
// EndpointStatus contains the status of either the source or destination endpoint.
2626
type EndpointStatus struct {
27-
Shards []ShardStatus `json:"shards,omitempty"`
27+
// Databases holds the replication status of all databases from the point of view of this endpoint.
28+
// List is ordered by name of the database.
29+
Databases []DatabaseStatus `json:"databases,omitempty"`
2830
}

pkg/apis/replication/v1alpha/replication_status.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ package v1alpha
2626
// an ArangoDeploymentReplication.
2727
type DeploymentReplicationStatus struct {
2828
// Phase holds the current lifetime phase of the deployment replication
29-
Phase DeploymentReplicationPhase `json:"phase"`
29+
Phase DeploymentReplicationPhase `json:"phase,omitempty"`
3030
// Reason contains a human readable reason for reaching the current phase (can be empty)
3131
Reason string `json:"reason,omitempty"` // Reason for current phase
3232

pkg/apis/replication/v1alpha/shard_status.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,5 @@ package v1alpha
2424

2525
// ShardStatus contains the status of a single shard.
2626
type ShardStatus struct {
27-
Database string `json:"database"`
28-
Collection string `json:"collection"`
29-
ShardIndex int `json:"shard"`
30-
Status string `json:"status"`
27+
Status string `json:"status"`
3128
}

pkg/apis/replication/v1alpha/zz_generated.deepcopy.go

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,27 @@ func (in *ArangoDeploymentReplicationList) DeepCopyObject() runtime.Object {
8989
return nil
9090
}
9191

92+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
93+
func (in *CollectionStatus) DeepCopyInto(out *CollectionStatus) {
94+
*out = *in
95+
if in.Shards != nil {
96+
in, out := &in.Shards, &out.Shards
97+
*out = make([]ShardStatus, len(*in))
98+
copy(*out, *in)
99+
}
100+
return
101+
}
102+
103+
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CollectionStatus.
104+
func (in *CollectionStatus) DeepCopy() *CollectionStatus {
105+
if in == nil {
106+
return nil
107+
}
108+
out := new(CollectionStatus)
109+
in.DeepCopyInto(out)
110+
return out
111+
}
112+
92113
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
93114
func (in *Condition) DeepCopyInto(out *Condition) {
94115
*out = *in
@@ -107,6 +128,29 @@ func (in *Condition) DeepCopy() *Condition {
107128
return out
108129
}
109130

131+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
132+
func (in *DatabaseStatus) DeepCopyInto(out *DatabaseStatus) {
133+
*out = *in
134+
if in.Collections != nil {
135+
in, out := &in.Collections, &out.Collections
136+
*out = make([]CollectionStatus, len(*in))
137+
for i := range *in {
138+
(*in)[i].DeepCopyInto(&(*out)[i])
139+
}
140+
}
141+
return
142+
}
143+
144+
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatabaseStatus.
145+
func (in *DatabaseStatus) DeepCopy() *DatabaseStatus {
146+
if in == nil {
147+
return nil
148+
}
149+
out := new(DatabaseStatus)
150+
in.DeepCopyInto(out)
151+
return out
152+
}
153+
110154
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
111155
func (in *DeploymentReplicationSpec) DeepCopyInto(out *DeploymentReplicationSpec) {
112156
*out = *in
@@ -219,10 +263,12 @@ func (in *EndpointSpec) DeepCopy() *EndpointSpec {
219263
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
220264
func (in *EndpointStatus) DeepCopyInto(out *EndpointStatus) {
221265
*out = *in
222-
if in.Shards != nil {
223-
in, out := &in.Shards, &out.Shards
224-
*out = make([]ShardStatus, len(*in))
225-
copy(*out, *in)
266+
if in.Databases != nil {
267+
in, out := &in.Databases, &out.Databases
268+
*out = make([]DatabaseStatus, len(*in))
269+
for i := range *in {
270+
(*in)[i].DeepCopyInto(&(*out)[i])
271+
}
226272
}
227273
return
228274
}

pkg/replication/sync_inspector.go

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ package replication
2424

2525
import (
2626
"context"
27+
"sort"
2728
"time"
2829

2930
"github.com/arangodb/arangosync/client"
@@ -240,28 +241,66 @@ func (dr *DeploymentReplication) hasOutgoingEndpoint(status client.SyncInfo, epS
240241
func createEndpointStatus(status client.SyncInfo, outgoingID string) api.EndpointStatus {
241242
result := api.EndpointStatus{}
242243
if outgoingID == "" {
243-
for _, s := range status.Shards {
244-
result.Shards = append(result.Shards, api.ShardStatus{
245-
Database: s.Database,
246-
Collection: s.Collection,
247-
ShardIndex: s.ShardIndex,
248-
Status: string(s.Status),
249-
})
244+
return createEndpointStatusFromShards(status.Shards)
245+
}
246+
for _, o := range status.Outgoing {
247+
if o.ID != outgoingID {
248+
continue
250249
}
251-
} else {
252-
for _, o := range status.Outgoing {
253-
if o.ID != outgoingID {
254-
continue
250+
return createEndpointStatusFromShards(o.Shards)
251+
}
252+
253+
return result
254+
}
255+
256+
// createEndpointStatusFromShards creates an api EndpointStatus from the given list of shard statuses.
257+
func createEndpointStatusFromShards(shards []client.ShardSyncInfo) api.EndpointStatus {
258+
result := api.EndpointStatus{}
259+
260+
getDatabase := func(name string) *api.DatabaseStatus {
261+
for i, d := range result.Databases {
262+
if d.Name == name {
263+
return &result.Databases[i]
255264
}
256-
for _, s := range o.Shards {
257-
result.Shards = append(result.Shards, api.ShardStatus{
258-
Database: s.Database,
259-
Collection: s.Collection,
260-
ShardIndex: s.ShardIndex,
261-
Status: string(s.Status),
262-
})
265+
}
266+
// Not found, add it
267+
result.Databases = append(result.Databases, api.DatabaseStatus{Name: name})
268+
return &result.Databases[len(result.Databases)-1]
269+
}
270+
271+
getCollection := func(db *api.DatabaseStatus, name string) *api.CollectionStatus {
272+
for i, c := range db.Collections {
273+
if c.Name == name {
274+
return &db.Collections[i]
263275
}
264276
}
277+
// Not found, add it
278+
db.Collections = append(db.Collections, api.CollectionStatus{Name: name})
279+
return &db.Collections[len(db.Collections)-1]
280+
}
281+
282+
// Sort shard by index
283+
sort.Slice(shards, func(i, j int) bool {
284+
return shards[i].ShardIndex < shards[j].ShardIndex
285+
})
286+
for _, s := range shards {
287+
db := getDatabase(s.Database)
288+
col := getCollection(db, s.Collection)
289+
290+
// Add "missing" shards if needed
291+
for len(col.Shards) < s.ShardIndex {
292+
col.Shards = append(col.Shards, api.ShardStatus{Status: ""})
293+
}
294+
295+
// Add current shard
296+
col.Shards = append(col.Shards, api.ShardStatus{Status: string(s.Status)})
297+
}
298+
299+
// Sort result
300+
sort.Slice(result.Databases, func(i, j int) bool { return result.Databases[i].Name < result.Databases[j].Name })
301+
for i, db := range result.Databases {
302+
sort.Slice(db.Collections, func(i, j int) bool { return db.Collections[i].Name < db.Collections[j].Name })
303+
result.Databases[i] = db
265304
}
266305
return result
267306
}

0 commit comments

Comments
 (0)