Skip to content

Commit fec5508

Browse files
committed
fix: deadlock occurs when updating configuration fails
1 parent 75d068a commit fec5508

File tree

1 file changed

+58
-85
lines changed

1 file changed

+58
-85
lines changed

internal/adc/client/client.go

Lines changed: 58 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -72,119 +72,92 @@ type Task struct {
7272
Resources *adctypes.Resources
7373
}
7474

75-
func (d *Client) Update(ctx context.Context, args Task) error {
75+
type StoreDelta struct {
76+
Deleted map[types.NamespacedNameKind]adctypes.Config
77+
Applied map[types.NamespacedNameKind]adctypes.Config
78+
}
79+
80+
func (d *Client) applyStoreChanges(args Task, isDelete bool) (StoreDelta, error) {
7681
d.mu.Lock()
77-
deleteConfigs := d.ConfigManager.Update(args.Key, args.Configs)
78-
for _, config := range deleteConfigs {
79-
if err := d.Store.Delete(config.Name, args.ResourceTypes, args.Labels); err != nil {
80-
log.Errorw("failed to delete resources from store",
81-
zap.String("name", config.Name),
82-
zap.Error(err),
83-
)
84-
return err
82+
defer d.mu.Unlock()
83+
84+
var delta StoreDelta
85+
86+
if isDelete {
87+
delta.Deleted = d.ConfigManager.Get(args.Key)
88+
d.ConfigManager.Delete(args.Key)
89+
} else {
90+
deleted := d.ConfigManager.Update(args.Key, args.Configs)
91+
delta.Deleted = deleted
92+
delta.Applied = args.Configs
93+
}
94+
95+
for _, cfg := range delta.Deleted {
96+
if err := d.Store.Delete(cfg.Name, args.ResourceTypes, args.Labels); err != nil {
97+
return StoreDelta{}, errors.Wrap(err, "store delete failed")
8598
}
8699
}
87100

88-
for _, config := range args.Configs {
89-
if err := d.Insert(config.Name, args.ResourceTypes, args.Resources, args.Labels); err != nil {
90-
log.Errorw("failed to insert resources into store",
91-
zap.String("name", config.Name),
92-
zap.Error(err),
93-
)
94-
return err
101+
for _, cfg := range delta.Applied {
102+
if err := d.Insert(cfg.Name, args.ResourceTypes, args.Resources, args.Labels); err != nil {
103+
return StoreDelta{}, errors.Wrap(err, "store insert failed")
95104
}
96105
}
97-
d.mu.Unlock()
98106

107+
return delta, nil
108+
}
109+
110+
func (d *Client) applySync(ctx context.Context, args Task, delta StoreDelta) error {
99111
d.syncMu.RLock()
100112
defer d.syncMu.RUnlock()
101113

102-
if len(deleteConfigs) > 0 {
103-
err := d.sync(ctx, Task{
114+
if len(delta.Deleted) > 0 {
115+
if err := d.sync(ctx, Task{
104116
Name: args.Name,
105117
Labels: args.Labels,
106118
ResourceTypes: args.ResourceTypes,
107-
Configs: deleteConfigs,
108-
})
109-
if err != nil {
119+
Configs: delta.Deleted,
120+
}); err != nil {
110121
log.Warnw("failed to sync deleted configs", zap.Error(err))
111122
}
112123
}
113124

114-
return d.sync(ctx, args)
125+
if len(delta.Applied) > 0 {
126+
return d.sync(ctx, Task{
127+
Name: args.Name,
128+
Labels: args.Labels,
129+
ResourceTypes: args.ResourceTypes,
130+
Configs: delta.Applied,
131+
Resources: args.Resources,
132+
})
133+
}
134+
return nil
115135
}
116136

117-
func (d *Client) UpdateConfig(ctx context.Context, args Task) error {
118-
d.mu.Lock()
119-
defer d.mu.Unlock()
120-
deleteConfigs := d.ConfigManager.Update(args.Key, args.Configs)
121-
122-
for _, config := range deleteConfigs {
123-
if err := d.Store.Delete(config.Name, args.ResourceTypes, args.Labels); err != nil {
124-
log.Errorw("failed to delete resources from store",
125-
zap.String("name", config.Name),
126-
zap.Error(err),
127-
)
128-
return err
129-
}
137+
func (d *Client) Update(ctx context.Context, args Task) error {
138+
delta, err := d.applyStoreChanges(args, false)
139+
if err != nil {
140+
return err
130141
}
142+
return d.applySync(ctx, args, delta)
143+
}
131144

132-
for _, config := range args.Configs {
133-
if err := d.Insert(config.Name, args.ResourceTypes, args.Resources, args.Labels); err != nil {
134-
log.Errorw("failed to insert resources into store",
135-
zap.String("name", config.Name),
136-
zap.Error(err),
137-
)
138-
return err
139-
}
140-
}
141-
return nil
145+
func (d *Client) UpdateConfig(ctx context.Context, args Task) error {
146+
_, err := d.applyStoreChanges(args, false)
147+
return err
142148
}
143149

144150
func (d *Client) Delete(ctx context.Context, args Task) error {
145-
d.mu.Lock()
146-
configs := d.ConfigManager.Get(args.Key)
147-
d.ConfigManager.Delete(args.Key)
148-
149-
for _, config := range configs {
150-
if err := d.Store.Delete(config.Name, args.ResourceTypes, args.Labels); err != nil {
151-
log.Errorw("failed to delete resources from store",
152-
zap.String("name", config.Name),
153-
zap.Error(err),
154-
)
155-
return err
156-
}
151+
delta, err := d.applyStoreChanges(args, true)
152+
if err != nil {
153+
return err
157154
}
158-
d.mu.Unlock()
159-
160-
d.syncMu.RLock()
161-
defer d.syncMu.RUnlock()
162-
163-
return d.sync(ctx, Task{
164-
Labels: args.Labels,
165-
ResourceTypes: args.ResourceTypes,
166-
Configs: configs,
167-
})
155+
return d.applySync(ctx, args, delta)
168156
}
169157

170158
func (d *Client) DeleteConfig(ctx context.Context, args Task) error {
171-
d.mu.Lock()
172-
defer d.mu.Unlock()
173-
174-
configs := d.ConfigManager.Get(args.Key)
175-
d.ConfigManager.Delete(args.Key)
176-
177-
for _, config := range configs {
178-
if err := d.Store.Delete(config.Name, args.ResourceTypes, args.Labels); err != nil {
179-
log.Errorw("failed to delete resources from store",
180-
zap.String("name", config.Name),
181-
zap.Error(err),
182-
)
183-
return err
184-
}
185-
}
186-
187-
return nil
159+
_, err := d.applyStoreChanges(args, true)
160+
return err
188161
}
189162

190163
func (c *Client) Sync(ctx context.Context) (map[string]types.ADCExecutionErrors, error) {

0 commit comments

Comments
 (0)