Skip to content

Commit ff08978

Browse files
committed
📖 Add a design for cache options configuration
1 parent c52016d commit ff08978

File tree

1 file changed

+216
-0
lines changed

1 file changed

+216
-0
lines changed

designs/cache_options.md

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

0 commit comments

Comments
 (0)