Skip to content

Commit dfd3b47

Browse files
authored
Merge pull request #923 from saikat-royc/999.0
Ensure max one running attach/detach operation for a given disk on an instance
2 parents a68d0b8 + ab4cead commit dfd3b47

File tree

15 files changed

+2201
-108
lines changed

15 files changed

+2201
-108
lines changed

pkg/common/cache.go

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*
2+
Copyright 2022 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package common
18+
19+
import (
20+
"fmt"
21+
)
22+
23+
type DiskInstanceKey string
24+
type InstanceKey string
25+
26+
type OpInfo struct {
27+
Name string
28+
Type string
29+
}
30+
31+
type DiskInstanceOpsMap struct {
32+
ops map[DiskInstanceKey]OpInfo
33+
}
34+
35+
func NewDiskInstanceOpsMap() *DiskInstanceOpsMap {
36+
return &DiskInstanceOpsMap{
37+
ops: make(map[DiskInstanceKey]OpInfo),
38+
}
39+
}
40+
41+
func (c *DiskInstanceOpsMap) GetOp(key DiskInstanceKey) *OpInfo {
42+
op, ok := c.ops[key]
43+
if !ok {
44+
return nil
45+
}
46+
return &op
47+
}
48+
49+
func (c *DiskInstanceOpsMap) ClearOp(key DiskInstanceKey, targetOpName string) error {
50+
op, ok := c.ops[key]
51+
if !ok {
52+
return nil
53+
}
54+
55+
if op.Name != targetOpName {
56+
return fmt.Errorf("For key %q, cannot clear op %q, cache already contains op %q", key, targetOpName, op.Name)
57+
}
58+
59+
delete(c.ops, key)
60+
return nil
61+
}
62+
63+
func (c *DiskInstanceOpsMap) AddOp(key DiskInstanceKey, targetOp OpInfo) {
64+
c.ops[key] = targetOp
65+
}
66+
67+
type InstanceOpsMap struct {
68+
ops map[InstanceKey][]OpInfo
69+
}
70+
71+
func NewInstanceOpsMap() *InstanceOpsMap {
72+
return &InstanceOpsMap{
73+
ops: make(map[InstanceKey][]OpInfo),
74+
}
75+
}
76+
77+
func (c *InstanceOpsMap) GetOps(key InstanceKey) []OpInfo {
78+
v, ok := c.ops[key]
79+
if !ok {
80+
return nil
81+
}
82+
return v
83+
}
84+
85+
func (c *InstanceOpsMap) ClearOp(key InstanceKey, targetOpName string) {
86+
ops, ok := c.ops[key]
87+
if !ok {
88+
return
89+
}
90+
91+
var filteredOps []OpInfo
92+
for _, o := range ops {
93+
if o.Name != targetOpName {
94+
filteredOps = append(filteredOps, o)
95+
}
96+
}
97+
if len(filteredOps) == 0 {
98+
delete(c.ops, key)
99+
return
100+
}
101+
102+
c.ops[key] = filteredOps
103+
}
104+
105+
func (c *InstanceOpsMap) AddOp(key InstanceKey, targetOp OpInfo) {
106+
ops, ok := c.ops[key]
107+
if !ok {
108+
c.ops[key] = []OpInfo{targetOp}
109+
return
110+
}
111+
112+
for _, o := range ops {
113+
if o.Name == targetOp.Name {
114+
return
115+
}
116+
}
117+
118+
ops = append(ops, targetOp)
119+
c.ops[key] = ops
120+
}
121+
122+
type OpsCache struct {
123+
InstanceOps *InstanceOpsMap
124+
DiskInstanceOps *DiskInstanceOpsMap
125+
}
126+
127+
func NewOpsCache() *OpsCache {
128+
return &OpsCache{
129+
InstanceOps: NewInstanceOpsMap(),
130+
DiskInstanceOps: NewDiskInstanceOpsMap(),
131+
}
132+
}
133+
134+
func CreateDiskInstanceKey(project, location, disk, instance string) DiskInstanceKey {
135+
return DiskInstanceKey(fmt.Sprintf("%s_%s_%s_%s", project, location, disk, instance))
136+
}
137+
138+
func CreateInstanceKey(project, location, instance string) InstanceKey {
139+
return InstanceKey(fmt.Sprintf("%s_%s_%s", project, location, instance))
140+
}

0 commit comments

Comments
 (0)