Skip to content

Commit 11ca71a

Browse files
OTA-1418: USC: Drop unknown messages from the API (#1143)
* USC: Drop unknown messages from the API Assume the informers, in each message, include a list of all active insight IDs that infomer knows about. The Status API can then drop the unknown insights formerly reported by that informer (=insights present in the API but not known to be active by the responsible informer) This is only a part of OTA-1418. The remaining changes will be as follows: - Do not drop the unknown insights right away but make them expire after some some time of not being renewed (handle the case where informer starts up and starts sending messages about insights as it discovers them) - Actually make the informers remember their insights and populate the `knownInsights` field of the message - Add additional `deletedInsights` field to the message, to allow informers explicitly tell the API some insight went away - Make the USC respect `deletedInsights` - Make informers fill `deletedInsight` - Potentially add a out-of-API memory cache for insights to be expired / deleted but allow them to reappear with formerly known content Co-authored-by: David Hurta <[email protected]> * Apply suggestions from code review Co-authored-by: David Hurta <[email protected]> * Fix comment formatting in updatestatuscontroller.go --------- Co-authored-by: David Hurta <[email protected]> Co-authored-by: David Hurta <[email protected]>
1 parent dc0568c commit 11ca71a

File tree

2 files changed

+56
-12
lines changed

2 files changed

+56
-12
lines changed

pkg/updatestatus/updatestatuscontroller.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/google/go-cmp/cmp"
1111
"gopkg.in/yaml.v3"
1212
corev1 "k8s.io/api/core/v1"
13+
"k8s.io/apimachinery/pkg/util/sets"
1314
"k8s.io/klog/v2"
1415

1516
"k8s.io/apimachinery/pkg/api/errors"
@@ -29,6 +30,11 @@ import (
2930
// we have the Status API we need to serialize ourselves anyway.
3031
type informerMsg struct {
3132
informer string
33+
// knownInsights contains the UIDs of insights known by the informer, so the controller can remove insights formerly
34+
// reported by the informer but no longer known to it (e.g. because the informer was restarted and the culprit
35+
// condition ceased to exist in the meantime). The `uid` of the insight in the message payload is always assumed
36+
// to be known, and is not required to be included in `knownInsights` by the informers (but informers can do so).
37+
knownInsights []string
3238

3339
uid string
3440
insight []byte
@@ -153,6 +159,7 @@ func (c *updateStatusController) processInsightMsg(message informerMsg) bool {
153159
}
154160
klog.Infof("USC :: Collector :: Received insight from informer %q (uid=%s)", message.informer, message.uid)
155161
c.updateInsightInStatusApi(message)
162+
c.removeUnknownInsights(message)
156163

157164
return true
158165
}
@@ -213,7 +220,21 @@ func (c *updateStatusController) updateInsightInStatusApi(msg informerMsg) {
213220
klog.Infof("USC :: Collector :: Insight (uid=%s) content did not change (len=%d)", msg.uid, len(updatedContent))
214221
}
215222
}
223+
}
216224

225+
// removeUnknownInsights removes insights from the status API that are no longer reported as known to the informer
226+
// that originally reported them.
227+
// Assumes the statusApi field is locked.
228+
func (c *updateStatusController) removeUnknownInsights(message informerMsg) {
229+
known := sets.New(message.knownInsights...)
230+
known.Insert(message.uid)
231+
informerPrefix := fmt.Sprintf("usc.%s.", message.informer)
232+
for key := range c.statusApi.cm.Data {
233+
if strings.HasPrefix(key, informerPrefix) && !known.Has(strings.TrimPrefix(key, informerPrefix)) {
234+
delete(c.statusApi.cm.Data, key)
235+
klog.V(2).Infof("USC :: Collector :: Dropped insight %q because it is no longer reported as known by informer %q", key, message.informer)
236+
}
237+
}
217238
}
218239

219240
func (c *updateStatusController) commitStatusApiAsConfigMap(ctx context.Context) error {

pkg/updatestatus/updatestatuscontroller_test.go

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,24 +77,28 @@ func Test_updateStatusController(t *testing.T) {
7777
},
7878
informerMsg: []informerMsg{
7979
{
80-
informer: "cpi",
81-
uid: "new-item",
82-
insight: []byte("msg1"),
80+
informer: "cpi",
81+
uid: "new-item",
82+
insight: []byte("msg1"),
83+
knownInsights: []string{"kept", "overwritten"},
8384
},
8485
{
85-
informer: "cpi",
86-
uid: "overwritten",
87-
insight: []byte("msg2 (overwritten intermediate)"),
86+
informer: "cpi",
87+
uid: "overwritten",
88+
insight: []byte("msg2 (overwritten intermediate)"),
89+
knownInsights: []string{"kept", "new-item"},
8890
},
8991
{
90-
informer: "cpi",
91-
uid: "another",
92-
insight: []byte("msg3"),
92+
informer: "cpi",
93+
uid: "another",
94+
insight: []byte("msg3"),
95+
knownInsights: []string{"kept", "overwritten", "new-item"},
9396
},
9497
{
95-
informer: "cpi",
96-
uid: "overwritten",
97-
insight: []byte("msg4 (overwritten final)"),
98+
informer: "cpi",
99+
uid: "overwritten",
100+
insight: []byte("msg4 (overwritten final)"),
101+
knownInsights: []string{"kept", "new-item", "another"},
98102
},
99103
},
100104
expected: &corev1.ConfigMap{
@@ -175,6 +179,25 @@ func Test_updateStatusController(t *testing.T) {
175179
},
176180
expected: nil,
177181
},
182+
{
183+
name: "unknown message gets removed from state",
184+
controllerConfigMap: &corev1.ConfigMap{
185+
Data: map[string]string{
186+
"usc.one.old": "payload",
187+
},
188+
},
189+
informerMsg: []informerMsg{{
190+
informer: "one",
191+
uid: "new",
192+
insight: []byte("new payload"),
193+
knownInsights: nil,
194+
}},
195+
expected: &corev1.ConfigMap{
196+
Data: map[string]string{
197+
"usc.one.new": "new payload",
198+
},
199+
},
200+
},
178201
}
179202

180203
for _, tc := range testCases {

0 commit comments

Comments
 (0)