Skip to content

Commit fc70a10

Browse files
authored
fix: trim the history annotation when the size is too big (#418)
* fix * add comment and format * add testcase
1 parent 5b4d56f commit fc70a10

File tree

2 files changed

+57
-5
lines changed

2 files changed

+57
-5
lines changed

simulator/scheduler/storereflector/storereflector.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"golang.org/x/xerrors"
1010
corev1 "k8s.io/api/core/v1"
1111
apierrors "k8s.io/apimachinery/pkg/api/errors"
12+
validation "k8s.io/apimachinery/pkg/api/validation"
1213
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1314
clientset "k8s.io/client-go/kubernetes"
1415
"k8s.io/client-go/tools/cache"
@@ -157,11 +158,19 @@ func updateResultHistory(p *corev1.Pod, m map[string]string) error {
157158

158159
results = append(results, m)
159160

160-
r, err := json.Marshal(results)
161-
if err != nil {
162-
return xerrors.Errorf("encode all results: %w", err)
161+
// If we exceed that annotation size limitation, we should drop entries from the oldest side
162+
// of the history slice until the payload fits, since the newer histories are likely more important.
163+
for ; len(results) != 0; results = results[1:] {
164+
r, err := json.Marshal(results)
165+
if err != nil {
166+
return xerrors.Errorf("encode all results: %w", err)
167+
}
168+
if len(r) <= validation.TotalAnnotationSizeLimitB {
169+
metav1.SetMetaDataAnnotation(&p.ObjectMeta, ResultsHistoryAnnotation, string(r))
170+
return nil
171+
}
163172
}
164-
metav1.SetMetaDataAnnotation(&p.ObjectMeta, ResultsHistoryAnnotation, string(r))
165173

166-
return nil
174+
// Basically shouldn't happen unless a single history entry is bigger than TotalAnnotationSizeLimitB, which is very unlikely.
175+
return xerrors.Errorf("result history still exceeds annotation limit even after removing several histories")
167176
}

simulator/scheduler/storereflector/storereflector_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package storereflector
33
import (
44
"context"
55
"fmt"
6+
"strings"
67
"testing"
78

89
"github.com/google/go-cmp/cmp"
@@ -129,6 +130,27 @@ func Test_updateResultHistory(t *testing.T) {
129130
},
130131
wantErr: assert.NoError,
131132
},
133+
{
134+
name: "success: trim oldest result history when exceeds annotation size limitation",
135+
p: &corev1.Pod{
136+
ObjectMeta: metav1.ObjectMeta{
137+
Annotations: map[string]string{
138+
ResultsHistoryAnnotation: fmt.Sprintf(`[{"result":"%s"}]`, strings.Repeat("a", 200000)),
139+
},
140+
},
141+
},
142+
m: map[string]string{
143+
"result": strings.Repeat("b", 200000),
144+
},
145+
wantPod: &corev1.Pod{
146+
ObjectMeta: metav1.ObjectMeta{
147+
Annotations: map[string]string{
148+
ResultsHistoryAnnotation: fmt.Sprintf(`[{"result":"%s"}]`, strings.Repeat("b", 200000)),
149+
},
150+
},
151+
},
152+
wantErr: assert.NoError,
153+
},
132154
{
133155
name: "fail: Pod has broken value on annotation",
134156
p: &corev1.Pod{
@@ -144,6 +166,27 @@ func Test_updateResultHistory(t *testing.T) {
144166
},
145167
wantErr: assert.Error,
146168
},
169+
{
170+
name: "fail: single result history exceeds annotation size limitation",
171+
p: &corev1.Pod{
172+
ObjectMeta: metav1.ObjectMeta{
173+
Annotations: map[string]string{
174+
ResultsHistoryAnnotation: "[]",
175+
},
176+
},
177+
},
178+
m: map[string]string{
179+
"result": strings.Repeat("a", 270000),
180+
},
181+
wantPod: &corev1.Pod{
182+
ObjectMeta: metav1.ObjectMeta{
183+
Annotations: map[string]string{
184+
ResultsHistoryAnnotation: "[]",
185+
},
186+
},
187+
},
188+
wantErr: assert.Error,
189+
},
147190
}
148191
for _, tt := range tests {
149192
tt := tt

0 commit comments

Comments
 (0)