When using knative.dev/metrics/pkg, the kubeclient has an unexpected dependency on the knative.dev/pkg/metrics pkg and its internal lock (metricsMux) that prevents the kubeclient from being used freely within the metrics pkg.
Here are the two uses of the metricsMux that don't play well.
knative.dev/pkg/metrics/exporter.go
k8s.io/client-go/
The effect of this is every call to kubeclient uses the metrics pkg to Record a metric, and needs to lock metricsMux. Every update to the metrics exporter needs to call the kubeclient, and needs to lock metricsMux.
This prevents fully locking the metrics exporter update section to prevent race conditions.
Ideally we find a way to make the kubeclient usable anywhere with the metrics package, or we make it very clear to developers that they cannot use it within a lock through a test that will fail or dev-oriented error.
Expected Behavior
You can use the client-go kubeclient while locked with the metricsMux.
Actual Behavior
Deadlock
Steps to Reproduce the Problem
Within the knative.dev/pkg/metrics pkg
- Add a call to metricsMux.Lock()
- Within the lock scope, attempt to use the client-go kubeclient
- Deadlock
import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
}
func someFunc() {
metricsMux.Lock()
defer metricsMux.Unlock()
config, _ := rest.InClusterConfig()
kubeclient, _ := kubernetes.NewForConfig(config)
kubeclient.CoreV1().Secrets("").Get("some-secret", metav1.GetOptions{})
// Never reach here
}
## Additional Info
When using knative.dev/metrics/pkg, the kubeclient has an unexpected dependency on the knative.dev/pkg/metrics pkg and its internal lock (metricsMux) that prevents the kubeclient from being used freely within the metrics pkg.
Here are the two uses of the metricsMux that don't play well.
knative.dev/pkg/metrics/exporter.go
k8s.io/client-go/
https://github.com/knative/pkg/blob/master/metrics/metrics.go#L115-126
The effect of this is every call to kubeclient uses the metrics pkg to Record a metric, and needs to lock metricsMux. Every update to the metrics exporter needs to call the kubeclient, and needs to lock metricsMux.
This prevents fully locking the metrics exporter update section to prevent race conditions.
Ideally we find a way to make the kubeclient usable anywhere with the metrics package, or we make it very clear to developers that they cannot use it within a lock through a test that will fail or dev-oriented error.
Expected Behavior
You can use the client-go kubeclient while locked with the metricsMux.
Actual Behavior
Deadlock
Steps to Reproduce the Problem
Within the knative.dev/pkg/metrics pkg