Skip to content

Commit

Permalink
Use SSE to track CRC status change and logs
Browse files Browse the repository at this point in the history
Signed-off-by: Yevhen Vydolob <[email protected]>
  • Loading branch information
evidolob committed Dec 7, 2023
1 parent caccc05 commit 83f8997
Show file tree
Hide file tree
Showing 9 changed files with 411 additions and 58 deletions.
2 changes: 2 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

import type { Preset } from './types';

export const PRE_SSE_VERSION = '2.30.0';

// copied from https://github.com/crc-org/crc/blob/632676d7c9ba0c030736c3d914984c4e140c1bf5/pkg/crc/constants/constants.go#L198

export function getDefaultCPUs(preset: Preset): number {
Expand Down
2 changes: 1 addition & 1 deletion src/crc-delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function registerDeleteCommand(): void {
}

export async function deleteCrc(suppressNotification = false): Promise<boolean> {
if (crcStatus.status.CrcStatus === 'No Cluster') {
if (crcStatus.status.CrcStatus === 'NoVM') {
if (!suppressNotification) {
await extensionApi.window.showNotification({
silent: false,
Expand Down
82 changes: 60 additions & 22 deletions src/crc-status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,23 @@

import * as extensionApi from '@podman-desktop/api';
import type { Status, CrcStatus as CrcStatusApi } from './types';
import { commander } from './daemon-commander';
import { commander, getCrcApiUrl } from './daemon-commander';
import { isNeedSetup } from './crc-setup';
import { EventSource } from './events/eventsource';
import type { CrcVersion } from './crc-cli';
import { compare } from 'compare-versions';
import { PRE_SSE_VERSION } from './constants';

const defaultStatus: Status = { CrcStatus: 'Unknown', Preset: 'openshift' };
const setupStatus: Status = { CrcStatus: 'Need Setup', Preset: 'Unknown' };
const errorStatus: Status = { CrcStatus: 'Error', Preset: 'Unknown' };

export class CrcStatus {
private updateTimer: NodeJS.Timer;
private _status: Status;
private isSetupGoing: boolean;
private statusEventSource: EventSource;
private crcVersion: CrcVersion;
private updateTimer: NodeJS.Timer;
private statusChangeEventEmitter = new extensionApi.EventEmitter<Status>();
public readonly onStatusChange = this.statusChangeEventEmitter.event;

Expand All @@ -37,30 +43,61 @@ export class CrcStatus {
}

startStatusUpdate(): void {
if (this.updateTimer) {
return; // we already set timer
}
this.updateTimer = setInterval(async () => {
try {
// we don't need to update status while setup is going
if (this.isSetupGoing) {
this._status = createStatus('Starting', this._status.Preset);
return;
if (compare(this.crcVersion.version, PRE_SSE_VERSION, '<=')) {
if (this.updateTimer) {
return; // we already set timer
}
this.updateTimer = setInterval(async () => {
try {
// we don't need to update status while setup is going
if (this.isSetupGoing) {
this._status = createStatus('Starting', this._status.Preset);
return;
}
const oldStatus = this._status;
this._status = await commander.status();
// notify listeners when status changed
if (oldStatus.CrcStatus !== this._status.CrcStatus) {
this.statusChangeEventEmitter.fire(this._status);
}
} catch (e) {
console.error('CRC Status tick: ' + e);
this._status = defaultStatus;
}
const oldStatus = this._status;
this._status = await commander.status();
// notify listeners when status changed
if (oldStatus.CrcStatus !== this._status.CrcStatus) {
}, 2000);
} else {
if (this.statusEventSource) {
return;
}

this.statusEventSource = new EventSource(getCrcApiUrl() + '/events?stream=status_change');
this.statusEventSource.on('status_change', (e: MessageEvent) => {
const data = e.data;
try {
if (this.isSetupGoing) {
this._status = createStatus('Starting', this._status.Preset);
return;
}
console.error(`On Status: ${data}`);
this._status = JSON.parse(data).status;
this.statusChangeEventEmitter.fire(this._status);
} catch (err) {
console.error(err);
this._status = defaultStatus;
}
} catch (e) {
console.error('CRC Status tick: ' + e);
});
this.statusEventSource.on('error', e => {
console.error(e);
this._status = defaultStatus;
}
}, 2000);
});
}
}

stopStatusUpdate(): void {
if (this.statusEventSource) {
this.statusEventSource.close();
this.statusEventSource = undefined;
}
if (this.updateTimer) {
clearInterval(this.updateTimer);
}
Expand All @@ -74,7 +111,8 @@ export class CrcStatus {
this._status = errorStatus;
}

async initialize(): Promise<void> {
async initialize(crcVersion: CrcVersion): Promise<void> {
this.crcVersion = crcVersion;
if (isNeedSetup) {
this._status = setupStatus;
return;
Expand Down Expand Up @@ -107,7 +145,7 @@ export class CrcStatus {
case 'Stopping':
return 'stopping';
case 'Stopped':
case 'No Cluster':
case 'NoVM':
return 'stopped';
default:
return 'unknown';
Expand All @@ -124,7 +162,7 @@ export class CrcStatus {
return 'stopping';
case 'Stopped':
return 'configured';
case 'No Cluster':
case 'NoVM':
return 'installed';
case 'Error':
return 'error';
Expand Down
15 changes: 9 additions & 6 deletions src/daemon-commander.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,18 @@ import got from 'got';
import { isWindows } from './util';
import type { ConfigKeys, Configuration, StartInfo, Status } from './types';

export function getCrcApiUrl(): string {
if (isWindows()) {
return 'http://unix://?/pipe/crc-http:';
}
return `http://unix:${process.env.HOME}/.crc/crc-http.sock:`;
}

export class DaemonCommander {
private apiPath: string;

constructor() {
this.apiPath = `http://unix:${process.env.HOME}/.crc/crc-http.sock:/api`;

if (isWindows()) {
this.apiPath = 'http://unix://?/pipe/crc-http:/api';
}
this.apiPath = getCrcApiUrl() + '/api';
}

async status(): Promise<Status> {
Expand All @@ -41,7 +44,7 @@ export class DaemonCommander {
} catch (error) {
// ignore status error, as it may happen when no cluster created
return {
CrcStatus: 'No Cluster',
CrcStatus: 'NoVM',
};
}
}
Expand Down
Loading

0 comments on commit 83f8997

Please sign in to comment.