mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix integration test and kube watches not working at all
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
883bd36028
commit
c0ba030785
@ -403,10 +403,11 @@ export class KubeApi<
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method differs from {@link formatUrlForNotListing} because this treats `""` as "all namespaces"
|
* This method differs from {@link formatUrlForNotListing} because this treats `""` as "all namespaces"
|
||||||
|
* NOTE: This is also useful for watching
|
||||||
* @param namespace The namespace to list in or `""` for all namespaces
|
* @param namespace The namespace to list in or `""` for all namespaces
|
||||||
*/
|
*/
|
||||||
formatUrlForListing(namespace: string) {
|
formatUrlForListing(namespace: string | undefined, query?: Partial<KubeApiQueryParams>) {
|
||||||
return createKubeApiURL({
|
const resourcePath = createKubeApiURL({
|
||||||
apiPrefix: this.apiPrefix,
|
apiPrefix: this.apiPrefix,
|
||||||
apiVersion: this.apiVersionWithGroup,
|
apiVersion: this.apiVersionWithGroup,
|
||||||
resource: this.apiResource,
|
resource: this.apiResource,
|
||||||
@ -414,15 +415,15 @@ export class KubeApi<
|
|||||||
? namespace ?? "default"
|
? namespace ?? "default"
|
||||||
: undefined,
|
: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return resourcePath + (query ? `?${stringify(this.normalizeQuery(query))}` : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a URL pathname and query for acting upon a specific resource.
|
* Format a URL pathname and query for acting upon a specific resource.
|
||||||
*/
|
*/
|
||||||
formatUrlForNotListing(resource?: Partial<ResourceDescriptor>, query?: Partial<KubeApiQueryParams>): string;
|
formatUrlForNotListing({ name, namespace }: Partial<ResourceDescriptor> = {}) {
|
||||||
|
return createKubeApiURL({
|
||||||
formatUrlForNotListing({ name, namespace }: Partial<ResourceDescriptor> = {}, query?: Partial<KubeApiQueryParams>) {
|
|
||||||
const resourcePath = createKubeApiURL({
|
|
||||||
apiPrefix: this.apiPrefix,
|
apiPrefix: this.apiPrefix,
|
||||||
apiVersion: this.apiVersionWithGroup,
|
apiVersion: this.apiVersionWithGroup,
|
||||||
resource: this.apiResource,
|
resource: this.apiResource,
|
||||||
@ -431,15 +432,17 @@ export class KubeApi<
|
|||||||
: undefined,
|
: undefined,
|
||||||
name,
|
name,
|
||||||
});
|
});
|
||||||
|
|
||||||
return resourcePath + (query ? `?${stringify(this.normalizeQuery(query))}` : "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated use {@link formatUrlForNotListing} instead
|
* @deprecated use {@link formatUrlForNotListing} or {@link formatUrlForListing} instead
|
||||||
*/
|
*/
|
||||||
getUrl(resource?: Partial<ResourceDescriptor>, query?: Partial<KubeApiQueryParams>) {
|
getUrl(resource?: Partial<ResourceDescriptor>, query?: Partial<KubeApiQueryParams>) {
|
||||||
return this.formatUrlForNotListing(resource, query);
|
if (query) {
|
||||||
|
return this.formatUrlForListing(resource?.namespace, query);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.formatUrlForNotListing(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected normalizeQuery(query: Partial<KubeApiQueryParams> = {}) {
|
protected normalizeQuery(query: Partial<KubeApiQueryParams> = {}) {
|
||||||
@ -625,14 +628,14 @@ export class KubeApi<
|
|||||||
}
|
}
|
||||||
|
|
||||||
getWatchUrl(namespace?: string, query: KubeApiQueryParams = {}) {
|
getWatchUrl(namespace?: string, query: KubeApiQueryParams = {}) {
|
||||||
return this.formatUrlForNotListing({ namespace }, {
|
return this.formatUrlForListing(namespace, {
|
||||||
watch: 1,
|
watch: 1,
|
||||||
resourceVersion: this.getResourceVersion(namespace),
|
resourceVersion: this.getResourceVersion(namespace),
|
||||||
...query,
|
...query,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(opts?: KubeApiWatchOptions<Object, Data>): () => void {
|
watch(opts?: KubeApiWatchOptions<Object, Data>): Disposer {
|
||||||
let errorReceived = false;
|
let errorReceived = false;
|
||||||
let timedRetry: NodeJS.Timeout;
|
let timedRetry: NodeJS.Timeout;
|
||||||
const {
|
const {
|
||||||
|
|||||||
@ -412,7 +412,7 @@ export abstract class KubeObjectStore<
|
|||||||
if (this.api.isNamespaced) {
|
if (this.api.isNamespaced) {
|
||||||
void (async () => {
|
void (async () => {
|
||||||
try {
|
try {
|
||||||
const [loadedNamespaces] = await Promise.race([
|
const loadedNamespaces = await Promise.race([
|
||||||
rejectPromiseBy(abortController.signal),
|
rejectPromiseBy(abortController.signal),
|
||||||
waitUntilDefined(() => this.loadedNamespaces.get()),
|
waitUntilDefined(() => this.loadedNamespaces.get()),
|
||||||
]);
|
]);
|
||||||
@ -424,8 +424,8 @@ export abstract class KubeObjectStore<
|
|||||||
this.watchNamespace(namespace, abortController, { onLoadFailure });
|
this.watchNamespace(namespace, abortController, { onLoadFailure });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (error) {
|
||||||
// ignore
|
console.error(`[KUBE-OBJECT-STORE]: failed to subscribe to ${this.api.apiBase}`, error);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
} else {
|
} else {
|
||||||
@ -441,7 +441,7 @@ export abstract class KubeObjectStore<
|
|||||||
}
|
}
|
||||||
|
|
||||||
let timedRetry: NodeJS.Timeout;
|
let timedRetry: NodeJS.Timeout;
|
||||||
const watch = () => this.api.watch({
|
const startNewWatch = () => this.api.watch({
|
||||||
namespace,
|
namespace,
|
||||||
abortController,
|
abortController,
|
||||||
callback,
|
callback,
|
||||||
@ -460,7 +460,7 @@ export abstract class KubeObjectStore<
|
|||||||
|
|
||||||
// not sure what to do, best to retry
|
// not sure what to do, best to retry
|
||||||
clearTimeout(timedRetry);
|
clearTimeout(timedRetry);
|
||||||
timedRetry = setTimeout(watch, 5000);
|
timedRetry = setTimeout(startNewWatch, 5000);
|
||||||
} else if (error instanceof KubeStatus && error.code === 410) {
|
} else if (error instanceof KubeStatus && error.code === 410) {
|
||||||
clearTimeout(timedRetry);
|
clearTimeout(timedRetry);
|
||||||
// resourceVersion has gone, let's try to reload
|
// resourceVersion has gone, let's try to reload
|
||||||
@ -469,11 +469,11 @@ export abstract class KubeObjectStore<
|
|||||||
namespace
|
namespace
|
||||||
? this.loadAll({ namespaces: [namespace], reqInit: { signal }, ...opts })
|
? this.loadAll({ namespaces: [namespace], reqInit: { signal }, ...opts })
|
||||||
: this.loadAll({ merge: false, reqInit: { signal }, ...opts })
|
: this.loadAll({ merge: false, reqInit: { signal }, ...opts })
|
||||||
).then(watch);
|
).then(startNewWatch);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
} else if (error) { // not sure what to do, best to retry
|
} else if (error) { // not sure what to do, best to retry
|
||||||
clearTimeout(timedRetry);
|
clearTimeout(timedRetry);
|
||||||
timedRetry = setTimeout(watch, 5000);
|
timedRetry = setTimeout(startNewWatch, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
@ -482,7 +482,7 @@ export abstract class KubeObjectStore<
|
|||||||
};
|
};
|
||||||
|
|
||||||
signal.addEventListener("abort", () => clearTimeout(timedRetry));
|
signal.addEventListener("abort", () => clearTimeout(timedRetry));
|
||||||
watch();
|
startNewWatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
|||||||
@ -8,26 +8,23 @@ import type { Disposer } from "./disposer";
|
|||||||
|
|
||||||
export async function waitUntilDefined<T>(getter: (() => T | null | undefined) | IComputedValue<T | null | undefined>, opts?: { timeout?: number }): Promise<T> {
|
export async function waitUntilDefined<T>(getter: (() => T | null | undefined) | IComputedValue<T | null | undefined>, opts?: { timeout?: number }): Promise<T> {
|
||||||
return new Promise<T>((resolve, reject) => {
|
return new Promise<T>((resolve, reject) => {
|
||||||
let res: T | null | undefined;
|
|
||||||
|
|
||||||
when(
|
when(
|
||||||
() => {
|
() => {
|
||||||
res = typeof getter === "function"
|
const res = typeof getter === "function"
|
||||||
? getter()
|
? getter()
|
||||||
: getter.get();
|
: getter.get();
|
||||||
|
const isDefined = res != null;
|
||||||
|
|
||||||
if (res != null) {
|
if (isDefined) {
|
||||||
resolve(res);
|
resolve(res);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return isDefined;
|
||||||
},
|
},
|
||||||
() => {},
|
() => {},
|
||||||
{
|
{
|
||||||
onError: reject,
|
onError: reject,
|
||||||
...opts,
|
...(opts ?? {}),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user