Skip to content

Commit 42a7e65

Browse files
authored
Docs best practices improvements and link fixes (#875)
1 parent dcc5f27 commit 42a7e65

File tree

2 files changed

+48
-6
lines changed

2 files changed

+48
-6
lines changed

docs/_includes/hero.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
{% endif %}
66
<h1 class="uk-heading-hero uk-text-bold uk-text-uppercase uk-text-muted uk-inline " style="font-family: 'Asap', sans-serif"> [ <small class="uk-margin-small-right uk-margin-small-left"> {{ site.title }} </small> ]</h1>
77
<div class="links uk-container uk-margin-medium-top">
8-
<a class="uk-button uk-button-small uk-border-pill uk-button-secondary uk-margin-small-bottom" href="{{ domain }}{{ link.url }}">
8+
<a class="uk-button uk-button-small uk-border-pill uk-button-secondary uk-margin-small-bottom" href="/docs/getting-started">
99
Get Started
1010
</a>
11-
<a class="uk-button uk-button-small uk-border-pill uk-button-default uk-margin-small-bottom " href="{{ domain }}{{ link.url }}">
11+
<a class="uk-button uk-button-small uk-border-pill uk-button-default uk-margin-small-bottom " href="/docs/contributing">
1212
<span uk-icon="github"></span> Contribute
1313
</a>
14-
<a class="uk-button uk-button-small uk-border-pill uk-button-default uk-margin-small-bottom" href="{{ domain }}{{ link.url }}">
14+
<a class="uk-button uk-button-small uk-border-pill uk-button-default uk-margin-small-bottom" href="https://discord.gg/DacEhAy">
1515
<span uk-icon="discord"></span> Discord Channel
1616
</a>
1717
</div>

docs/documentation/patterns-best-practices.md

+45-3
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,59 @@ permalink: /docs/patterns-best-practices
77

88
# Patterns and Best Practices
99

10-
This document describes patters and best practices, to build and run operators, and how to implement them in terms
11-
of Java Operator SDK.
10+
This document describes patterns and best practices, to build and run operators, and how to implement them in terms of
11+
Java Operator SDK.
12+
13+
See also best practices in [Operator SDK](https://sdk.operatorframework.io/docs/best-practices/best-practices/).
1214

1315
## Implementing a Reconciler
1416

17+
### Reconcile All The Resources All the Time
18+
19+
The reconciliation can be triggered by events from multiple sources. It could be tempting to check the events and
20+
reconcile just the related resource or subset of resources that the controller manages. However, this is **considered as an
21+
anti-pattern** in operators. If triggered, all resources should be reconciled. Usually this means only
22+
comparing the target state with the current state in the cache for most of the resource.
23+
The reason behind this is events not reliable in generally, this means events can be lost. In addition to that operator
24+
can crash and while down will miss events.
25+
26+
In addition to that such approach might even complicate implementation logic in the `Reconciler`, since parallel
27+
execution of the reconciler is not allowed for the same custom resource, there can be multiple events received for the
28+
same resource or dependent resource during an ongoing execution, ordering those events could be also challenging.
29+
30+
Since there is a consensus regarding this in the industry, from v2 the events are not even accessible for
31+
the `Reconciler`.
32+
1533
### Idempotency
1634

17-
### Sync of Async Way of Resource Handling
35+
Since all the resources are reconciled during an execution and an execution can be triggered quite often, also
36+
retries of a reconciliation can happen naturally in operators, the implementation of a `Reconciler`
37+
needs to be idempotent. Luckily, since operators are usually managing already declarative resources, this is trivial
38+
to do in most cases.
39+
40+
### Sync or Async Way of Resource Handling
41+
42+
In an implementation of reconciliation there can be a point when reconciler needs to wait a non-insignificant amount
43+
of time while a resource gets up and running. For example, reconciler would do some additional step only if a Pod is ready
44+
to receive requests. This problem can be approached in two ways synchronously or asynchronously.
45+
46+
The async way is just return from the reconciler, if there are informers properly in place for the target resource,
47+
reconciliation will be triggered on change. During the reconciliation the pod can be read from the cache of the informer
48+
and a check on it's state can be conducted again. The benefit of this approach is that it will free up the thread,
49+
so it can be used to reconcile other resources.
50+
51+
The sync way would be to periodically poll the cache of the informer for the pod's state, until the target state
52+
is reached. This would block the thread until the state is reached, which in some cases could take quite long.
1853

1954
## Why to Have Automated Retries?
2055

56+
Automatic retries are in place by default, it can be fine-tuned, but in general it's not advised to turn
57+
of automatic retries. One of the reason is that, issues like network error naturally happens, and are usually
58+
solved by a retry. Another typical situation is for example when a dependent resource or the custom resource is updated,
59+
during the update usually there is optimistic version control in place. So if someone updated the resource during
60+
reconciliation, maybe using `kubectl` or another process, the update would fail on a conflict. A retry solves this
61+
problem simply by executing the reconciliation again.
62+
2163
## Managing State
2264

2365
## Dependent Resources

0 commit comments

Comments
 (0)