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.doneHandler invokes ListWatch.addOrUpdateItems with all new items. code
ListWatch.addOrUpdateItems iterates over all items returned from the API Server and calls addOrUpdateObject for each item. code
addOrUpdateObject calls findKubernetesObject which calls objects.findIndex which 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 2500350012
Expected 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
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 intoListWatch.objectsis 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.test.mjs
Test context
Expected behavior
It seems reasonable that insertion is O(n) if possible.
** Example Code**
N/A
Environment (please complete the following information):