1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

replace cluster warning event polling with watches

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
Jari Kolehmainen 2020-11-25 15:22:52 +02:00
parent 6a92372f50
commit 3237084b33
3 changed files with 59 additions and 18 deletions

View File

@ -42,7 +42,6 @@ export interface ClusterState {
accessible: boolean; accessible: boolean;
ready: boolean; ready: boolean;
failureReason: string; failureReason: string;
eventCount: number;
isAdmin: boolean; isAdmin: boolean;
allowedNamespaces: string[] allowedNamespaces: string[]
allowedResources: string[] allowedResources: string[]
@ -74,7 +73,6 @@ export class Cluster implements ClusterModel, ClusterState {
@observable disconnected = true; // false if user has selected to connect @observable disconnected = true; // false if user has selected to connect
@observable failureReason: string; @observable failureReason: string;
@observable isAdmin = false; @observable isAdmin = false;
@observable eventCount = 0;
@observable preferences: ClusterPreferences = {}; @observable preferences: ClusterPreferences = {};
@observable metadata: ClusterMetadata = {}; @observable metadata: ClusterMetadata = {};
@observable allowedNamespaces: string[] = []; @observable allowedNamespaces: string[] = [];
@ -209,10 +207,7 @@ export class Cluster implements ClusterModel, ClusterState {
await this.refreshConnectionStatus(); await this.refreshConnectionStatus();
if (this.accessible) { if (this.accessible) {
this.isAdmin = await this.isClusterAdmin(); this.isAdmin = await this.isClusterAdmin();
await Promise.all([ await this.refreshAllowedResources();
this.refreshEvents(),
this.refreshAllowedResources(),
]);
if (opts.refreshMetadata) { if (opts.refreshMetadata) {
this.refreshMetadata(); this.refreshMetadata();
} }
@ -242,11 +237,6 @@ export class Cluster implements ClusterModel, ClusterState {
this.allowedResources = await this.getAllowedResources(); this.allowedResources = await this.getAllowedResources();
} }
@action
async refreshEvents() {
this.eventCount = await this.getEventCount();
}
protected getKubeconfig(): KubeConfig { protected getKubeconfig(): KubeConfig {
return loadConfig(this.kubeConfigPath); return loadConfig(this.kubeConfigPath);
} }
@ -393,7 +383,6 @@ export class Cluster implements ClusterModel, ClusterState {
accessible: this.accessible, accessible: this.accessible,
failureReason: this.failureReason, failureReason: this.failureReason,
isAdmin: this.isAdmin, isAdmin: this.isAdmin,
eventCount: this.eventCount,
allowedNamespaces: this.allowedNamespaces, allowedNamespaces: this.allowedNamespaces,
allowedResources: this.allowedResources, allowedResources: this.allowedResources,
}; };

View File

@ -37,13 +37,16 @@ import { webFrame } from "electron";
import { clusterPageRegistry, getExtensionPageUrl, PageRegistration, RegisteredPage } from "../../extensions/registries/page-registry"; import { clusterPageRegistry, getExtensionPageUrl, PageRegistration, RegisteredPage } from "../../extensions/registries/page-registry";
import { extensionLoader } from "../../extensions/extension-loader"; import { extensionLoader } from "../../extensions/extension-loader";
import { appEventBus } from "../../common/event-bus"; import { appEventBus } from "../../common/event-bus";
import { requestMain } from "../../common/ipc"; import { broadcastMessage, requestMain } from "../../common/ipc";
import whatInput from 'what-input'; import whatInput from 'what-input';
import { clusterSetFrameIdHandler } from "../../common/cluster-ipc"; import { clusterSetFrameIdHandler } from "../../common/cluster-ipc";
import { ClusterPageMenuRegistration, clusterPageMenuRegistry } from "../../extensions/registries"; import { ClusterPageMenuRegistration, clusterPageMenuRegistry } from "../../extensions/registries";
import { TabLayoutRoute, TabLayout } from "./layout/tab-layout"; import { TabLayoutRoute, TabLayout } from "./layout/tab-layout";
import { Trans } from "@lingui/macro"; import { StatefulSetScaleDialog } from "./+workloads-statefulsets/statefulset-scale-dialog";
import {StatefulSetScaleDialog} from "./+workloads-statefulsets/statefulset-scale-dialog"; import { eventStore } from "./+events/event.store";
import { reaction, computed } from "mobx";
import { nodesStore } from "./+nodes/nodes.store";
import { podsStore } from "./+workloads-pods/pods.store";
@observer @observer
export class App extends React.Component { export class App extends React.Component {
@ -69,6 +72,32 @@ export class App extends React.Component {
whatInput.ask(); // Start to monitor user input device whatInput.ask(); // Start to monitor user input device
} }
async componentDidMount() {
console.log("hello");
const cluster = getHostedCluster();
await eventStore.loadAll();
await nodesStore.loadAll();
await podsStore.loadAll();
eventStore.subscribe();
nodesStore.subscribe();
podsStore.subscribe();
reaction(() => this.warningsCount, (count) => {
broadcastMessage(`cluster-warning-event-count:${cluster.id}`, count);
});
}
@computed
get warningsCount() {
let warnings = 0;
nodesStore.items.forEach(node => {
warnings = warnings + node.getWarningConditions().length;
});
warnings = warnings + eventStore.getWarnings().length;
return warnings;
}
get startURL() { get startURL() {
if (isAllowedResource(["events", "nodes", "pods"])) { if (isAllowedResource(["events", "nodes", "pods"])) {
return clusterURL(); return clusterURL();

View File

@ -1,13 +1,17 @@
import "./cluster-icon.scss"; import "./cluster-icon.scss";
import React, { DOMAttributes } from "react"; import React, { DOMAttributes } from "react";
import { observer } from "mobx-react"; import { disposeOnUnmount, observer } from "mobx-react";
import { Params as HashiconParams } from "@emeraldpay/hashicon"; import { Params as HashiconParams } from "@emeraldpay/hashicon";
import { Hashicon } from "@emeraldpay/hashicon-react"; import { Hashicon } from "@emeraldpay/hashicon-react";
import { Cluster } from "../../../main/cluster"; import { Cluster } from "../../../main/cluster";
import { cssNames, IClassName } from "../../utils"; import { cssNames, IClassName } from "../../utils";
import { Badge } from "../badge"; import { Badge } from "../badge";
import { Tooltip } from "../tooltip"; import { Tooltip } from "../tooltip";
import { eventStore } from "../+events/event.store";
import { forCluster } from "../../api/kube-api";
import { subscribeToBroadcast, unsubscribeAllFromBroadcast } from "../../../common/ipc";
import { observable, when } from "mobx";
interface Props extends DOMAttributes<HTMLElement> { interface Props extends DOMAttributes<HTMLElement> {
cluster: Cluster; cluster: Cluster;
@ -29,12 +33,31 @@ const defaultProps: Partial<Props> = {
export class ClusterIcon extends React.Component<Props> { export class ClusterIcon extends React.Component<Props> {
static defaultProps = defaultProps as object; static defaultProps = defaultProps as object;
@observable eventCount = 0;
get eventCountBroadcast() {
return `cluster-warning-event-count:${this.props.cluster.id}`;
}
componentDidMount() {
const subscriber = subscribeToBroadcast(this.eventCountBroadcast, (ev, eventCount) => {
if (eventCount != this.eventCount) {
this.eventCount = eventCount;
}
});
disposeOnUnmount(this, [
subscriber
]);
}
render() { render() {
const { const {
cluster, showErrors, showTooltip, errorClass, options, interactive, isActive, cluster, showErrors, showTooltip, errorClass, options, interactive, isActive,
children, ...elemProps children, ...elemProps
} = this.props; } = this.props;
const { isAdmin, name, eventCount, preferences, id: clusterId } = cluster; const { name, preferences, id: clusterId } = cluster;
const eventCount = this.eventCount;
const { icon } = preferences; const { icon } = preferences;
const clusterIconId = `cluster-icon-${clusterId}`; const clusterIconId = `cluster-icon-${clusterId}`;
const className = cssNames("ClusterIcon flex inline", this.props.className, { const className = cssNames("ClusterIcon flex inline", this.props.className, {
@ -48,7 +71,7 @@ export class ClusterIcon extends React.Component<Props> {
)} )}
{icon && <img src={icon} alt={name}/>} {icon && <img src={icon} alt={name}/>}
{!icon && <Hashicon value={clusterId} options={options}/>} {!icon && <Hashicon value={clusterId} options={options}/>}
{showErrors && isAdmin && eventCount > 0 && ( {showErrors && eventCount > 0 && !isActive && (
<Badge <Badge
className={cssNames("events-count", errorClass)} className={cssNames("events-count", errorClass)}
label={eventCount >= 1000 ? Math.ceil(eventCount / 1000) + "k+" : eventCount} label={eventCount >= 1000 ? Math.ceil(eventCount / 1000) + "k+" : eventCount}