Skip to content

Commit 0e24ee3

Browse files
authored
[Feature] Agency Cache (#850)
1 parent ac35757 commit 0e24ee3

23 files changed

+562
-156
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A)
44
- Add ArangoBackup backoff functionality
55
- Allow to abort ArangoBackup uploads by removing spec.upload
6+
- Add Agency Cache internally
67

78
## [1.2.5](https://github.com/arangodb/kube-arangodb/tree/1.2.5) (2021-10-25)
89
- Split & Unify Lifecycle management functionality

pkg/deployment/agency.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2016-2021 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+
21+
package deployment
22+
23+
import "github.com/arangodb/kube-arangodb/pkg/metrics"
24+
25+
var (
26+
inspectDeploymentAgencyIndex = metrics.MustRegisterGaugeVec(metricsComponent, "inspect_deployment_agency_index", "Index of the agency cache", metrics.DeploymentName)
27+
inspectDeploymentAgencyFetches = metrics.MustRegisterCounterVec(metricsComponent, "inspect_deployment_agency_fetches", "Number of agency fetches", metrics.DeploymentName)
28+
inspectDeploymentAgencyErrors = metrics.MustRegisterCounterVec(metricsComponent, "inspect_deployment_agency_errors", "Number of agency errors", metrics.DeploymentName)
29+
)

pkg/deployment/agency/cache.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2016-2021 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+
21+
package agency
22+
23+
import (
24+
"context"
25+
"sync"
26+
27+
"github.com/arangodb/go-driver/agency"
28+
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
29+
)
30+
31+
type Cache interface {
32+
Reload(ctx context.Context, client agency.Agency) (uint64, error)
33+
Data() (State, bool)
34+
CommitIndex() uint64
35+
}
36+
37+
func NewCache(mode *api.DeploymentMode) Cache {
38+
if mode.Get() == api.DeploymentModeSingle {
39+
return NewSingleCache()
40+
}
41+
42+
return NewAgencyCache()
43+
}
44+
45+
func NewAgencyCache() Cache {
46+
return &cache{}
47+
}
48+
49+
func NewSingleCache() Cache {
50+
return &cacheSingle{}
51+
}
52+
53+
type cacheSingle struct {
54+
}
55+
56+
func (c cacheSingle) CommitIndex() uint64 {
57+
return 0
58+
}
59+
60+
func (c cacheSingle) Reload(ctx context.Context, client agency.Agency) (uint64, error) {
61+
return 0, nil
62+
}
63+
64+
func (c cacheSingle) Data() (State, bool) {
65+
return State{}, true
66+
}
67+
68+
type cache struct {
69+
lock sync.Mutex
70+
71+
valid bool
72+
73+
commitIndex uint64
74+
75+
data State
76+
}
77+
78+
func (c *cache) CommitIndex() uint64 {
79+
return c.commitIndex
80+
}
81+
82+
func (c *cache) Data() (State, bool) {
83+
c.lock.Lock()
84+
defer c.lock.Unlock()
85+
86+
return c.data, c.valid
87+
}
88+
89+
func (c *cache) Reload(ctx context.Context, client agency.Agency) (uint64, error) {
90+
c.lock.Lock()
91+
defer c.lock.Unlock()
92+
93+
c.valid = false
94+
95+
cfg, err := getAgencyConfig(ctx, client)
96+
if err != nil {
97+
return cfg.CommitIndex, err
98+
}
99+
100+
if cfg.CommitIndex == c.commitIndex {
101+
// We are on same index, nothing to do
102+
return cfg.CommitIndex, err
103+
}
104+
105+
if data, err := loadState(ctx, client); err != nil {
106+
return cfg.CommitIndex, err
107+
} else {
108+
c.data = data
109+
c.valid = true
110+
c.commitIndex = cfg.CommitIndex
111+
return cfg.CommitIndex, err
112+
}
113+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2016-2021 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+
21+
package agency

pkg/deployment/agency/maintenance.go renamed to pkg/deployment/agency/config.go

Lines changed: 26 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -17,60 +17,52 @@
1717
//
1818
// Copyright holder is ArangoDB GmbH, Cologne, Germany
1919
//
20-
// Author Adam Janikowski
21-
//
2220

2321
package agency
2422

2523
import (
2624
"context"
25+
"encoding/json"
2726
"net/http"
2827

29-
"github.com/arangodb/go-driver/agency"
30-
3128
"github.com/arangodb/go-driver"
29+
"github.com/arangodb/go-driver/agency"
3230
)
3331

34-
func GetMaintenanceMode(ctx context.Context, client agency.Agency) (bool, error) {
35-
var data interface{}
36-
err := client.ReadKey(ctx, []string{"arango", "Supervision", "Maintenance"}, &data)
37-
38-
if err == nil {
39-
// We got 200
40-
return true, nil
41-
}
32+
func getAgencyConfig(ctx context.Context, client agency.Agency) (*agencyConfig, error) {
33+
conn := client.Connection()
4234

43-
if agency.IsKeyNotFound(err) {
44-
return false, nil
35+
req, err := client.Connection().NewRequest(http.MethodGet, "/_api/agency/config")
36+
if err != nil {
37+
return nil, err
4538
}
4639

47-
return false, err
48-
}
49-
50-
func SetMaintenanceMode(ctx context.Context, client driver.Client, enabled bool) error {
51-
data := "on"
52-
if !enabled {
53-
data = "off"
54-
}
40+
var data []byte
5541

56-
conn := client.Connection()
57-
r, err := conn.NewRequest(http.MethodPut, "/_admin/cluster/maintenance")
42+
resp, err := conn.Do(driver.WithRawResponse(ctx, &data), req)
5843
if err != nil {
59-
return err
44+
return nil, err
6045
}
6146

62-
if _, err := r.SetBody(data); err != nil {
63-
return err
47+
if err := resp.CheckStatus(http.StatusOK); err != nil {
48+
return nil, err
6449
}
6550

66-
resp, err := conn.Do(ctx, r)
67-
if err != nil {
68-
return err
69-
}
51+
var c agencyConfig
7052

71-
if err := resp.CheckStatus(http.StatusOK); err != nil {
72-
return err
53+
if err := json.Unmarshal(data, &c); err != nil {
54+
return nil, err
7355
}
7456

75-
return nil
57+
return &c, nil
58+
}
59+
60+
type agencyConfig struct {
61+
LeaderId string `json:"leaderId"`
62+
63+
CommitIndex uint64 `json:"commitIndex"`
64+
65+
Configuration struct {
66+
ID string `json:"id"`
67+
} `json:"configuration"`
7668
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2016-2021 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+
21+
package agency
22+
23+
import (
24+
"encoding/json"
25+
"testing"
26+
27+
"github.com/stretchr/testify/require"
28+
)
29+
30+
func Test_Config_Unmarshal(t *testing.T) {
31+
data := `{
32+
"term": 0,
33+
"leaderId": "AGNT-fd0f4fc7-b60b-44bb-9f5e-5fc91f708f82",
34+
"commitIndex": 94,
35+
"lastCompactionAt": 0,
36+
"nextCompactionAfter": 500,
37+
"lastAcked": {
38+
"AGNT-fd0f4fc7-b60b-44bb-9f5e-5fc91f708f82": {
39+
"lastAckedTime": 0,
40+
"lastAckedIndex": 94
41+
}
42+
},
43+
"configuration": {
44+
"pool": {
45+
"AGNT-fd0f4fc7-b60b-44bb-9f5e-5fc91f708f82": "tcp://[::1]:4001"
46+
},
47+
"active": [
48+
"AGNT-fd0f4fc7-b60b-44bb-9f5e-5fc91f708f82"
49+
],
50+
"id": "AGNT-fd0f4fc7-b60b-44bb-9f5e-5fc91f708f82",
51+
"agency size": 1,
52+
"pool size": 1,
53+
"endpoint": "tcp://[::1]:4001",
54+
"min ping": 1,
55+
"max ping": 5,
56+
"timeoutMult": 1,
57+
"supervision": true,
58+
"supervision frequency": 1,
59+
"compaction step size": 500,
60+
"compaction keep size": 50000,
61+
"supervision grace period": 10,
62+
"supervision ok threshold": 5,
63+
"version": 2,
64+
"startup": "origin"
65+
},
66+
"engine": "rocksdb",
67+
"version": "3.10.0-devel"
68+
}`
69+
70+
var cfg agencyConfig
71+
72+
require.NoError(t, json.Unmarshal([]byte(data), &cfg))
73+
74+
require.Equal(t, "AGNT-fd0f4fc7-b60b-44bb-9f5e-5fc91f708f82", cfg.LeaderId)
75+
require.Equal(t, uint64(94), cfg.CommitIndex)
76+
require.Equal(t, "AGNT-fd0f4fc7-b60b-44bb-9f5e-5fc91f708f82", cfg.Configuration.ID)
77+
}

pkg/deployment/agency/agency.go renamed to pkg/deployment/agency/current_collections.go

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,15 @@
1717
//
1818
// Copyright holder is ArangoDB GmbH, Cologne, Germany
1919
//
20-
// Author Adam Janikowski
21-
//
2220

2321
package agency
2422

25-
import (
26-
"context"
27-
28-
"github.com/arangodb/kube-arangodb/pkg/util/errors"
29-
30-
"github.com/arangodb/go-driver/agency"
31-
)
23+
type StateCurrentCollections map[string]StateCurrentDBCollections
3224

33-
type Fetcher func(ctx context.Context, i interface{}, keyParts ...string) error
25+
type StateCurrentDBCollections map[string]StateCurrentDBCollection
3426

35-
func NewFetcher(a agency.Agency) Fetcher {
36-
return func(ctx context.Context, i interface{}, keyParts ...string) error {
37-
if err := a.ReadKey(ctx, []string{
38-
ArangoKey,
39-
PlanKey,
40-
PlanCollectionsKey,
41-
}, i); err != nil {
42-
return errors.WithStack(err)
43-
}
27+
type StateCurrentDBCollection map[string]StateCurrentDBShard
4428

45-
return nil
46-
}
29+
type StateCurrentDBShard struct {
30+
Servers []string `json:"servers,omitempty"`
4731
}

0 commit comments

Comments
 (0)