Skip to content

Commit 8f637fe

Browse files
committed
📖 Add a design for cache options configuration
1 parent d989e66 commit 8f637fe

File tree

1 file changed

+226
-0
lines changed

1 file changed

+226
-0
lines changed

designs/cache_options.md

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
Cache Options
2+
===================
3+
4+
This document describes how we imagine the cache options to look in
5+
the future.
6+
7+
## Goals
8+
9+
* Align everyone on what settings on the cache we want to support and
10+
their configuration surface
11+
* Ensure that we support both complicated cache setups and provide an
12+
intuitive configuration UX
13+
14+
## Non-Goals
15+
16+
* Describe the design and implementation of the cache itself.
17+
The assumption is that the most granular level we will end up with is
18+
"per-object multiple namespaces with distinct selectors" and that this
19+
can be implemented using a "meta cache" that delegates per object and by
20+
extending the current multi-namespace cache
21+
* Outline any kind of timeline for when these settings will be implemented.
22+
Implementation will happen gradually over time whenever someone steps up
23+
to do the actual work
24+
25+
## Proposal
26+
27+
28+
```
29+
const (
30+
AllNamespaces = corev1.NamespaceAll
31+
)
32+
33+
type Config struct {
34+
// LabelSelector specifies a label selector. A nil value allows to
35+
// default this.
36+
LabelSelector labels.Selector
37+
38+
// FieldSelector specifics a field selector. A nil value allows to
39+
// default this.
40+
FieldSelector fields.Selector
41+
42+
// Transform specifies a transform func. A nil value allows to default
43+
// this.
44+
Transform toolscache.TransformFunc
45+
46+
// UnsafeDisableDeepCopy specifies if List and Get requests against the
47+
// cache should not DeepCopy. A nil value allows to default this.
48+
UnsafeDisableDeepCopy *bool
49+
}
50+
51+
52+
type ByObject struct {
53+
// Namespaces maps a namespace name to cache setting. If set, only the
54+
// namespaces in this map will be cached.
55+
//
56+
// Settings in the map value that are unset because either the value as a
57+
// whole is nil or because the specific setting is nil will be defaulted.
58+
// Use an empty value for the specific setting to prevent that.
59+
//
60+
// It is possible to have specific CacheSettings for just some namespaces
61+
// but cache all namespaces by using the AllNamespaces const as the map key.
62+
// This wil then include all namespaces that do not have a more specific
63+
// setting.
64+
//
65+
// A nil map allows to default this to the cache's DefaultNamespaces setting.
66+
// An empty map prevents this.
67+
//
68+
// This must be unset for cluster-scoped objects.
69+
Namespaces map[string]*CacheSetting
70+
71+
// CacheSettings will be used for cluster-scoped objects and to default
72+
// CacheSettings in the Namespaces field.
73+
//
74+
// It gets defaulted from DefaultLabelSelector, DefaultFieldSelector,
75+
// DefaultUnsafeDisableDeepCopy and DefaultTransform.
76+
CacheSettings *CacheSetting
77+
}
78+
79+
type Options struct {
80+
// ByObject specifies per-object cache settings. If unset for a given
81+
// object, this will fall through to Default* settings.
82+
ByObject map[client.Object]*ByObject
83+
84+
// DefaultNamespaces maps namespace names to cache settings. If set, it
85+
// will be usd for all objects that have a nil Namespaces setting.
86+
//
87+
// It is possible to have specific CacheSettings for just some namespaces
88+
// but cache all namespaces by using the `AllNamespaces` const as the map
89+
// key. This wil then include all namespaces that do not have a more
90+
// specific setting.
91+
//
92+
// The options in the CacheSettings that are nil will be defaulted from
93+
// the respective Default* settings.
94+
DefaultNamespaces map[string]*CacheSetting
95+
96+
// DefaultLabelSelector is the label selector that will be used as
97+
// the default field label selector for everything that doesn't
98+
// have one configured.
99+
DefaultLabelSelector labels.Selector
100+
101+
// DefaultFieldSelector is the field selector that will be used as
102+
// the default field selector for everything that doesn't have
103+
// one configured.
104+
DefaultFieldSelector fields.Selector
105+
106+
// DefaultUnsafeDisableDeepCopy is the default for UnsafeDisableDeepCopy
107+
// for everything that doesn't specify this.
108+
DefaultUnsafeDisableDeepCopy *bool
109+
110+
// DefaultTransform will be used as transform for all object types
111+
// unless they have a more specific transform set in ByObject.
112+
DefaultTransform toolscache.TransformFunc
113+
114+
// HTTPClient is the http client to use for the REST client
115+
HTTPClient *http.Client
116+
117+
// Scheme is the scheme to use for mapping objects to GroupVersionKinds
118+
Scheme *runtime.Scheme
119+
120+
// Mapper is the RESTMapper to use for mapping GroupVersionKinds to Resources
121+
Mapper meta.RESTMapper
122+
123+
// SyncPeriod determines the minimum frequency at which watched resources are
124+
// reconciled. A lower period will correct entropy more quickly, but reduce
125+
// responsiveness to change if there are many watched resources. Change this
126+
// value only if you know what you are doing. Defaults to 10 hours if unset.
127+
// there will a 10 percent jitter between the SyncPeriod of all controllers
128+
// so that all controllers will not send list requests simultaneously.
129+
//
130+
// This applies to all controllers.
131+
//
132+
// A period sync happens for two reasons:
133+
// 1. To insure against a bug in the controller that causes an object to not
134+
// be requeued, when it otherwise should be requeued.
135+
// 2. To insure against an unknown bug in controller-runtime, or its dependencies,
136+
// that causes an object to not be requeued, when it otherwise should be
137+
// requeued, or to be removed from the queue, when it otherwise should not
138+
// be removed.
139+
//
140+
// If you want
141+
// 1. to insure against missed watch events, or
142+
// 2. to poll services that cannot be watched,
143+
// then we recommend that, instead of changing the default period, the
144+
// controller requeue, with a constant duration `t`, whenever the controller
145+
// is "done" with an object, and would otherwise not requeue it, i.e., we
146+
// recommend the `Reconcile` function return `reconcile.Result{RequeueAfter: t}`,
147+
// instead of `reconcile.Result{}`.
148+
SyncPeriod *time.Duration
149+
150+
}
151+
```
152+
153+
154+
## Example usages
155+
156+
### Cache ConfigMaps in the `public` and `kube-system` namespaces and Secrets in the `operator` Namespace
157+
158+
159+
```
160+
cache.Options{
161+
ByObject: map[client.Object]*cache.ByObject{
162+
&corev1.ConfigMap{}: {
163+
Namespaces: map[string]*cache.CacheSetting{
164+
"public": {},
165+
"kube-system": {},
166+
},
167+
},
168+
&corev1.Secret{}: {Namespaces: map[string]*CacheSetting{
169+
"operator": {},
170+
}},
171+
},
172+
}
173+
```
174+
175+
### Cache ConfigMaps in all namespaces without selector, but have a selector for the `operator` Namespace
176+
177+
```
178+
cache.Options{
179+
ByObject: map[client.Object]*cache.ByObject{
180+
&corev1.ConfigMap{}: {
181+
Namespaces: map[string]*cache.CacheSetting{
182+
cache.AllNamespaces: nil, // No selector for all namespaces...
183+
"operator": {LabelSelector: labelSelector}, // except for the operator namespace
184+
},
185+
},
186+
},
187+
}
188+
```
189+
190+
191+
### Only cache the `operator` namespace for namespaced objects and all namespaces for Deployments
192+
193+
```
194+
cache.Options{
195+
ByObject: map[client.Object]*cache.ByObject{
196+
&appsv1.Deployment: {Namespaces: map[string]*cache.CacheSetting{
197+
cache.AllNamespaces: nil,
198+
}},
199+
},
200+
DefaultNamespaces: map[string]*cache.CacheSetting{
201+
"operator": nil,
202+
},
203+
}
204+
```
205+
206+
### Use a LabelSelector for everything except Nodes
207+
208+
```
209+
cache.Options{
210+
ByObject: map[client.Object]*cache.ByObject{
211+
&corev1.Node: {LabelSelector: labels.Everything()},
212+
},
213+
DefaultLabelSelector: myLabelSelector,
214+
}
215+
```
216+
217+
### Only cache namespaced objects in the `foo` and `bar` namespace
218+
219+
```
220+
cache.Options{
221+
DefaultNamespaces: map[string]*cache.CacheSetting{
222+
"foo": nil,
223+
"bar": nil,
224+
}
225+
}
226+
```

0 commit comments

Comments
 (0)