Skip to content

Commit 95f7cfa

Browse files
committed
GT-526 Use agency cache lock in metrics exporter
1 parent 7819c2b commit 95f7cfa

File tree

8 files changed

+65
-9
lines changed

8 files changed

+65
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
- (Documentation) Update ArangoDeploymentReplication and ArangoLocalStorage CR auto-generated docs
1515
- (Feature) Add ArangoMember Message and extend ArangoMember CRD
1616
- (Documentation) Use OpenAPI-compatible type names in docs
17+
- (Improvement) Use agency cache lock in metrics exporter
1718

1819
## [1.2.34](https://github.com/arangodb/kube-arangodb/tree/1.2.34) (2023-10-16)
1920
- (Bugfix) Fix make manifests-crd-file command

pkg/deployment/agency/cache.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,9 @@ type Health interface {
144144

145145
type Cache interface {
146146
Reload(ctx context.Context, size int, clients Connections) (uint64, error)
147-
Data() (state.State, bool)
147+
// Data returns current state. If no state is available, false is returned.
148+
// Use lock to access data which can be changed by reload.
149+
Data() (state.State, *sync.RWMutex, bool)
148150
DataDB() (state.DB, bool)
149151
CommitIndex() uint64
150152
// Health returns true when healthy object is available.
@@ -202,8 +204,8 @@ func (c cacheSingle) Reload(_ context.Context, _ int, _ Connections) (uint64, er
202204
return 0, nil
203205
}
204206

205-
func (c cacheSingle) Data() (state.State, bool) {
206-
return state.State{}, true
207+
func (c cacheSingle) Data() (state.State, *sync.RWMutex, bool) {
208+
return state.State{}, nil, true
207209
}
208210

209211
type cache struct {
@@ -232,16 +234,16 @@ func (c *cache) CommitIndex() uint64 {
232234
return index
233235
}
234236

235-
func (c *cache) Data() (state.State, bool) {
237+
func (c *cache) Data() (state.State, *sync.RWMutex, bool) {
236238
c.lock.RLock()
237239
defer c.lock.RUnlock()
238240

239241
data, _, ok := c.loader.State()
240242
if ok {
241-
return data.Arango, true
243+
return data.Arango, &c.lock, true
242244
}
243245

244-
return state.State{}, false
246+
return state.State{}, nil, false
245247
}
246248

247249
func (c *cache) DataDB() (state.DB, bool) {

pkg/deployment/deployment.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,16 @@ func (d *Deployment) GetMembersState() memberState.StateInspector {
159159
return d.memberState
160160
}
161161

162-
func (d *Deployment) GetAgencyCache() (state.State, bool) {
162+
func (d *Deployment) GetAgencyCacheWithLock() (state.State, *sync.RWMutex, bool) {
163163
return d.agencyCache.Data()
164164
}
165165

166+
// Deprecated: Use GetAgencyCacheWithLock instead
167+
func (d *Deployment) GetAgencyCache() (state.State, bool) {
168+
data, _, err := d.agencyCache.Data()
169+
return data, err
170+
}
171+
166172
func (d *Deployment) GetAgencyHealth() (agency.Health, bool) {
167173
return d.agencyCache.Health()
168174
}

pkg/deployment/old_metrics.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ func (i *inventory) CollectMetrics(in metrics.PushMetric) {
9292
}
9393

9494
if spec.Mode.Get().HasAgents() {
95-
agency, agencyOk := deployment.GetAgencyCache()
95+
// We get here a copy of the object, not a pointer
96+
agency, lock, agencyOk := deployment.GetAgencyCacheWithLock()
9697
if !agencyOk {
9798
in.Push(i.deploymentAgencyStateMetric.Gauge(0, deployment.GetNamespace(), deployment.GetName()))
9899
continue
@@ -101,6 +102,7 @@ func (i *inventory) CollectMetrics(in metrics.PushMetric) {
101102
in.Push(i.deploymentAgencyStateMetric.Gauge(1, deployment.GetNamespace(), deployment.GetName()))
102103

103104
if spec.Mode.Get() == api.DeploymentModeCluster {
105+
lock.RLock()
104106
for db, collections := range agency.Current.Collections {
105107
dbName := db
106108
if features.SensitiveInformationProtection().Enabled() {
@@ -142,6 +144,7 @@ func (i *inventory) CollectMetrics(in metrics.PushMetric) {
142144
}
143145
}
144146
}
147+
lock.RUnlock()
145148
}
146149
}
147150
}

pkg/deployment/reconcile/action_context.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ package reconcile
2222

2323
import (
2424
"context"
25+
"sync"
2526
"time"
2627

2728
core "k8s.io/api/core/v1"
@@ -260,6 +261,10 @@ func (ac *actionContext) ShardsInSyncMap() (state.ShardsSyncStatus, bool) {
260261
return ac.context.ShardsInSyncMap()
261262
}
262263

264+
func (ac *actionContext) GetAgencyCacheWithLock() (state.State, *sync.RWMutex, bool) {
265+
return ac.context.GetAgencyCacheWithLock()
266+
}
267+
263268
func (ac *actionContext) GetAgencyCache() (state.State, bool) {
264269
return ac.context.GetAgencyCache()
265270
}

pkg/deployment/reconcile/plan_builder_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"context"
2525
"fmt"
2626
"io"
27+
"sync"
2728
"testing"
2829

2930
monitoringClient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/typed/monitoring/v1"
@@ -176,6 +177,10 @@ func (c *testContext) GenerateMemberEndpoint(group api.ServerGroup, member api.M
176177
return pod2.GenerateMemberEndpoint(c.Inspector, c.ArangoDeployment, c.ArangoDeployment.Spec, group, member)
177178
}
178179

180+
func (c *testContext) GetAgencyCacheWithLock() (state.State, *sync.RWMutex, bool) {
181+
return state.State{}, nil, true
182+
}
183+
179184
func (c *testContext) GetAgencyCache() (state.State, bool) {
180185
return state.State{}, true
181186
}

pkg/deployment/reconciler/context.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ package reconciler
2222

2323
import (
2424
"context"
25-
2625
core "k8s.io/api/core/v1"
26+
"sync"
2727

2828
"github.com/arangodb/arangosync-client/client"
2929
"github.com/arangodb/go-driver"
@@ -96,6 +96,10 @@ type DeploymentImageManager interface {
9696
}
9797

9898
type ArangoAgencyGet interface {
99+
// GetAgencyCacheWithLock returns current Agency state, if no state is available, false is returned.
100+
// Use lock to access data which can be changed by reload.
101+
GetAgencyCacheWithLock() (state.State, *sync.RWMutex, bool)
102+
// Deprecated: Use GetAgencyCacheWithLock instead
99103
GetAgencyCache() (state.State, bool)
100104
GetAgencyArangoDBCache() (state.DB, bool)
101105
GetAgencyHealth() (agencyCache.Health, bool)

pkg/kuba/start.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package main
2+
3+
type one struct {
4+
Item two
5+
}
6+
7+
type two struct {
8+
Map map[string]string
9+
}
10+
11+
var kuba = &one{
12+
Item: two{
13+
Map: map[string]string{
14+
"foo": "bar",
15+
},
16+
},
17+
}
18+
19+
func main() {
20+
copy := getKuba()
21+
copy.Item.Map["foo"] = "baz"
22+
23+
println(kuba.Item.Map["foo"])
24+
println(copy.Item.Map["foo"])
25+
26+
}
27+
28+
func getKuba() one {
29+
return *kuba
30+
}

0 commit comments

Comments
 (0)