How?
If you are using the controller-runtime, it’s easy:
func (r *SomeReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&examplev1.Something{}).
WithOptions(controller.Options{
// This allows 10 goroutines to run Reconcile() simultaneously
MaxConcurrentReconciles: 10,
}).
Complete(r)
}
Internally go work queue is used.
If not, the documentation of the work queue package explains it best what is needed:
Package workqueue provides a simple queue that supports the following features:
- Fair: items processed in the order in which they are added.
- Stingy: a single item will not be processed multiple times concurrently, and if an item is added multiple times before it can be processed, it will only be processed once.
- Multiple consumers and producers. In particular, it is allowed for an item to be reenqueued while it is being processed. In this case it will be processed again.
- Shutdown notifications.
Race Conditions
The are multiple stages for preventing race conditions from happening.
- Work Queues are used internally by the controller-runtime
- With the help of resourceVersion to prevent updates on stale resources
- Following an Idempotent approach to writing operator logic.