mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix rerendering of KubeObject views every 30s (#4801)
Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
105 files changed
+1442
-709
No files matched your search
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
import { comparer, computed } from "mobx";
|
||||
import hostedClusterInjectable from "./hosted-cluster.injectable";
|
||||
|
||||
const allowedResourcesInjectable = getInjectable({
|
||||
instantiate: (di) => {
|
||||
const cluster = di.inject(hostedClusterInjectable);
|
||||
|
||||
return computed(() => new Set(cluster.allowedResources), {
|
||||
// This needs to be here so that during refresh changes are only propogated when necessary
|
||||
equals: (cur, prev) => comparer.structural(cur, prev),
|
||||
});
|
||||
},
|
||||
lifecycle: lifecycleEnum.singleton,
|
||||
});
|
||||
|
||||
export default allowedResourcesInjectable;
|
||||
+2
-2
@@ -3,8 +3,8 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
import { getHostedClusterId } from "../../utils";
|
||||
import clusterStoreInjectable from "../cluster-store.injectable";
|
||||
import { getHostedClusterId } from "../utils";
|
||||
import clusterStoreInjectable from "./cluster-store.injectable";
|
||||
|
||||
const hostedClusterInjectable = getInjectable({
|
||||
instantiate: (di) => {
|
||||
@@ -7,7 +7,7 @@ import yaml from "js-yaml";
|
||||
import { formatDuration } from "../../utils";
|
||||
import capitalize from "lodash/capitalize";
|
||||
import { apiBase } from "../index";
|
||||
import { helmChartStore } from "../../../renderer/components/+apps-helm-charts/helm-chart.store";
|
||||
import { helmChartStore } from "../../../renderer/components/+helm-charts/helm-chart.store";
|
||||
import type { ItemObject } from "../../item.store";
|
||||
import { KubeObject } from "../kube-object";
|
||||
import type { JsonApiData } from "../json-api";
|
||||
|
||||
@@ -16,12 +16,9 @@ import { KubeObjectConstructor, KubeObject, KubeStatus } from "./kube-object";
|
||||
import byline from "byline";
|
||||
import type { IKubeWatchEvent } from "./kube-watch-event";
|
||||
import { KubeJsonApi, KubeJsonApiData } from "./kube-json-api";
|
||||
import { noop } from "../utils";
|
||||
import { noop, WrappedAbortController } from "../utils";
|
||||
import type { RequestInit } from "node-fetch";
|
||||
|
||||
// BUG: https://github.com/mysticatea/abort-controller/pull/22
|
||||
// eslint-disable-next-line import/no-named-as-default
|
||||
import AbortController from "abort-controller";
|
||||
import type AbortController from "abort-controller";
|
||||
import { Agent, AgentOptions } from "https";
|
||||
import type { Patch } from "rfc6902";
|
||||
|
||||
@@ -582,14 +579,7 @@ export class KubeApi<T extends KubeObject> {
|
||||
const { watchId = `${this.kind.toLowerCase()}-${this.watchId++}` } = opts;
|
||||
|
||||
// Create AbortController for this request
|
||||
const abortController = new AbortController();
|
||||
|
||||
// If caller aborts, abort using request's abortController
|
||||
if (opts.abortController) {
|
||||
opts.abortController.signal.addEventListener("abort", () => {
|
||||
abortController.abort();
|
||||
});
|
||||
}
|
||||
const abortController = new WrappedAbortController(opts.abortController);
|
||||
|
||||
abortController.signal.addEventListener("abort", () => {
|
||||
logger.info(`[KUBE-API] watch (${watchId}) aborted ${watchUrl}`);
|
||||
@@ -687,7 +677,6 @@ export class KubeApi<T extends KubeObject> {
|
||||
protected modifyWatchEvent(event: IKubeWatchEvent<KubeJsonApiData>) {
|
||||
if (event.type === "ERROR") {
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
ensureObjectSelfLink(this, event.object);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import type { ClusterContext } from "./cluster-context";
|
||||
|
||||
import { action, computed, makeObservable, observable, reaction, when } from "mobx";
|
||||
import { autoBind, noop, rejectPromiseBy } from "../utils";
|
||||
import { autoBind, Disposer, noop, rejectPromiseBy } from "../utils";
|
||||
import { KubeObject, KubeStatus } from "./kube-object";
|
||||
import type { IKubeWatchEvent } from "./kube-watch-event";
|
||||
import { ItemStore } from "../item.store";
|
||||
@@ -378,7 +378,7 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
|
||||
});
|
||||
}
|
||||
|
||||
subscribe({ onLoadFailure, abortController = new AbortController() }: KubeObjectStoreSubscribeParams = {}) {
|
||||
subscribe({ onLoadFailure, abortController = new AbortController() }: KubeObjectStoreSubscribeParams = {}): Disposer {
|
||||
if (this.api.isNamespaced) {
|
||||
Promise.race([rejectPromiseBy(abortController.signal), Promise.all([this.contextReady, this.namespacesReady])])
|
||||
.then(() => {
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { appsRoute } from "./apps";
|
||||
import { helmRoute } from "./helm";
|
||||
|
||||
export const helmChartsRoute: RouteProps = {
|
||||
path: `${appsRoute.path}/charts/:repo?/:chartName?`,
|
||||
path: `${helmRoute.path}/charts/:repo?/:chartName?`,
|
||||
};
|
||||
|
||||
export interface HelmChartsRouteParams {
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
|
||||
export const appsRoute: RouteProps = {
|
||||
path: "/apps",
|
||||
export const helmRoute: RouteProps = {
|
||||
path: "/helm",
|
||||
};
|
||||
|
||||
export const appsURL = buildURL(appsRoute.path);
|
||||
export const helmURL = buildURL(helmRoute.path);
|
||||
@@ -4,7 +4,6 @@
|
||||
*/
|
||||
|
||||
export * from "./add-cluster";
|
||||
export * from "./apps";
|
||||
export * from "./catalog";
|
||||
export * from "./cluster-view";
|
||||
export * from "./cluster";
|
||||
@@ -16,6 +15,7 @@ export * from "./entity-settings";
|
||||
export * from "./events";
|
||||
export * from "./extensions";
|
||||
export * from "./helm-charts";
|
||||
export * from "./helm";
|
||||
export * from "./hpa";
|
||||
export * from "./ingresses";
|
||||
export * from "./limit-ranges";
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
import { appsRoute } from "./apps";
|
||||
import { helmRoute } from "./helm";
|
||||
|
||||
export const releaseRoute: RouteProps = {
|
||||
path: `${appsRoute.path}/releases/:namespace?/:name?`,
|
||||
path: `${helmRoute.path}/releases/:namespace?/:name?`,
|
||||
};
|
||||
|
||||
export interface ReleaseRouteParams {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import AbortController from "abort-controller";
|
||||
|
||||
export class WrappedAbortController extends AbortController {
|
||||
constructor(parent?: AbortController) {
|
||||
super();
|
||||
|
||||
parent?.signal.addEventListener("abort", () => {
|
||||
this.abort();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { ClusterStore } from "../cluster-store/cluster-store";
|
||||
import type { KubeResource } from "../rbac";
|
||||
import { getHostedClusterId } from "./cluster-id-url-parsing";
|
||||
|
||||
export function isAllowedResource(resource: KubeResource | KubeResource[]) {
|
||||
const resources = [resource].flat();
|
||||
const cluster = ClusterStore.getInstance().getById(getHostedClusterId());
|
||||
|
||||
if (!cluster?.allowedResources) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (resources.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const allowedResources = new Set(cluster.allowedResources);
|
||||
|
||||
return resources.every(resource => allowedResources.has(resource));
|
||||
}
|
||||
@@ -10,6 +10,7 @@ export function noop<T extends any[]>(...args: T): void {
|
||||
return void args;
|
||||
}
|
||||
|
||||
export * from "./abort-controller";
|
||||
export * from "./app-version";
|
||||
export * from "./autobind";
|
||||
export * from "./camelCase";
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
import allowedResourcesInjectable from "../cluster-store/allowed-resources.injectable";
|
||||
import type { KubeResource } from "../rbac";
|
||||
|
||||
export type IsAllowedResource = (resource: KubeResource) => boolean;
|
||||
|
||||
// TODO: This injectable obscures MobX de-referencing. Make it more apparent in usage.
|
||||
const isAllowedResourceInjectable = getInjectable({
|
||||
instantiate: (di) => {
|
||||
const allowedResources = di.inject(allowedResourcesInjectable);
|
||||
|
||||
return (resource: KubeResource) => allowedResources.get().has(resource);
|
||||
},
|
||||
|
||||
lifecycle: lifecycleEnum.singleton,
|
||||
});
|
||||
|
||||
export default isAllowedResourceInjectable;
|
||||
Reference in new issue
Block a user