-
Notifications
You must be signed in to change notification settings - Fork 562
Description
Describe the bug
When a list watch is created (or any other time listWatch.resourceVersion === ''), the ListWatch will attempt to bootstrap its list of objects. Insertion of items from the API Server's List response into ListWatch.objects is n^2, and can be very slow for very large quantities of objects (on the order of 100K).
In particular:
ListWatch.doneHandlerinvokesListWatch.addOrUpdateItemswith all new items. codeListWatch.addOrUpdateItemsiterates over all items returned from the API Server and callsaddOrUpdateObjectfor each item. codeaddOrUpdateObjectcallsfindKubernetesObjectwhich callsobjects.findIndexwhich again goes over all items. code
** Client Version **
1.0.0-rc6
** Server Version **
1.29.8 (Although I don't think this is relevant)
To Reproduce
I added a shim into cache.js in the @kubernetes/client-node package to keep track of how many times a object in cache was accessed via findKubernetesObject.
function findKubernetesObject(objects, obj) {
return objects.findIndex((elt) => {
++global.accesses; // This is the only addition
return isSameObject(elt, obj);
});
}test.mjs
import * as k8s from '@kubernetes/client-node';
const apiUrl = '/apis/v1/namespaces/default/configmaps';
global.accesses = 0;
const kc = new k8s.KubeConfig(); kc.loadFromDefault();
const watch = new k8s.Watch(kc);
const client = kc.makeApiClient(k8s.CoreV1Api);
const lw = new k8s.ListWatch(
apiUrl,
watch,
async () => {
const x = await client.listNamespacedConfigMap({namespace: 'default'});
console.log('fetched items', x.items.length);
return x;
},
false
);
const start = performance.now();
await lw.start()
console.log('elapsed', performance.now() - start);
console.log('object accesses', accesses)Test context
$ minikube start
...
$ seq 50000 | xargs -P 100 -I'{}' kubectl create cm cm-'{}'
...
$ node test.mjs
fetched items 50004
elapsed 12140.640042
object accesses 2500350012Expected behavior
It seems reasonable that insertion is O(n) if possible.
** Example Code**
N/A
Environment (please complete the following information):
- OS: Linux
- NodeJS Version: 20
- Cloud runtime: EKS + Minikube