With this change, we can typically avoid an extra heap allocation when
calling AddAfter with a positive duration (which causes the creation of
a waitFor object). This is because workqueues are typically used with
string keys, and casting a string (or more generally, non-pointer types)
to an `interface{}` will cause an heap escape / allocation.
Ater this change, there is no longer any usage of `type t interface{}`,
which was creating some confusion after the switch to generics in the
workqueue package.
Co-authored-by: Quan Tian <quan.tian@broadcom.com>
Signed-off-by: Antonin Bas <antonin.bas@broadcom.com>
Kubernetes-commit: 53ddffb55709857fec6bddbd5ca4ca1b03f7da97
The workqueue implementation was recently updated to be strongly typed,
using Go generics. However the metrics implementation was not updated,
and continued using interface{}. This translated to unnecessary memory
allocations when invoking the queueMetrics interface methods to track
queue operation. We can avoid these extra heap allocations by using
generics for the metrics implementation as well.
Signed-off-by: Antonin Bas <antonin.bas@broadcom.com>
Kubernetes-commit: 1aec7568e111f5855121e3afacacf431e5f95948
This change adds a generic version of the various workqueue types while
retaining compatibility for the existing exported symbols and constructors.
The generic variants are prefixed with `Typed` and the existing ones are
marked as deprecated to nudge people to transition without breaking
them.
Kubernetes-commit: 0c7370bb851c15825d30a516722139ccccca0cfc
The default queue implementation is mostly FIFO and it is not
exchangeable unless we implement the whole `workqueue.Interface` which
is less desirable as we have to duplicate a lot of code. There was one
attempt done in [kubernetes/kubernetes#109349][1] which tried to
implement a priority queue. That is really useful and [knative/pkg][2]
implemented something called two-lane-queue. While two lane queue is
great, but isn't perfect since a full slow queue can still slow down
items in fast queue.
This change proposes a swappable queue implementation while not adding
extra maintenance effort in kubernetes community. We are happy to
maintain our own queue implementation (similar to two-lane-queue) in
downstream.
[1]: https://github.com/kubernetes/kubernetes/pull/109349
[2]: https://github.com/knative/pkg/blob/main/controller/two_lane_queue.go
Kubernetes-commit: 87b4279e07349b3c68f16f69a349a02bddd12f25
It turned out that there were lots of unnecessary accessor functions being called locking and unlocking the cond which are not needed because Wait() automatically unlocks and locks the cond for us and best practice says we should run it in a for checking for the condition (so this is what I have done).
Kubernetes-commit: 2b12df56b0be93bc2cac7c5a66342c0ffaa72311
Problem:
When calling newQueue metrics can be of type noMetrics when just calling
New. When doing this a new goroutine is created to update the metrics
but in this case there are no metrics so it's just creating goroutines
that don't do anything but consume resources.
Solution:
If the incoming metrics is of type noMetrics, don't start the goroutine
Kubernetes-commit: de021396f81ff438899297a6f464c70113b58475