Skip to content
This repository has been archived by the owner on Aug 29, 2023. It is now read-only.

Commit

Permalink
Addresses #150
Browse files Browse the repository at this point in the history
  • Loading branch information
forman committed Apr 30, 2021
1 parent aec7eab commit 4c6a667
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 15 deletions.
8 changes: 7 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
### Changes 2.3.0 (in development)
### Changes 3.0 (in development)

* Cate App 3.0 now requires the Web API service of the `cate 3.0+`
Python package.

* In order to keep alive the connection to the Web API service,
Cate App now sends a keepalive signal every 2.5 seconds. (#150)

* Optimisations in the DATA SOURCES panel (that have been enabled by
using [xcube](https://xcube.readthedocs.io/) in the backend):
Expand Down
38 changes: 28 additions & 10 deletions src/renderer/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,29 +314,47 @@ export function connectWebAPIService(webAPIServiceURL: string): ThunkAction {

const webAPIClient = newWebAPIClient(selectors.apiWebSocketsUrlSelector(getState()));

const formatMessage = (message: string, event: any): string => {
if (event.message) {
return `${message} (${event.message})`;
} else {
return message;
}
};

/**
* Called to inform backend we are still alive.
* Hopefully avoids closing WebSocket connection.
*/
const keepAlive = () => {
if (webAPIClient.isOpen) {
console.debug("calling keep_alive()");
webAPIClient.call('keep_alive', [])
}
};

let keepAliveTimer = null;

webAPIClient.onOpen = () => {
dispatch(setWebAPIClient(webAPIClient));
dispatch(loadBackendConfig());
dispatch(loadColorMaps());
dispatch(loadPreferences());
dispatch(loadDataStores());
dispatch(loadOperations());
};

const formatMessage = (message: string, event: any): string => {
if (event.message) {
return `${message} (${event.message})`;
} else {
return message;
}
keepAliveTimer = setInterval(keepAlive, 2500);
};

webAPIClient.onClose = (event) => {
if (keepAliveTimer !== null) {
clearInterval(keepAliveTimer);
}
const webAPIStatus = getState().communication.webAPIStatus;
if (webAPIStatus === 'shuttingDown' || webAPIStatus === 'loggingOut') {
// When we are logging off, the webAPIClient is expected to close.
return;
}
// When we end up here, the connection closed unintentionally.
console.error('webAPIClient.onClose:', event);
dispatch(setWebAPIStatus('closed'));
showToast({type: 'notification', text: formatMessage('Connection to Cate service closed', event)});
Expand All @@ -355,8 +373,8 @@ export function connectWebAPIService(webAPIServiceURL: string): ThunkAction {
};
}

export function updateHubStatus(hubStatus: HubStatus): Action {
return { type: UPDATE_HUB_STATUS, payload: hubStatus};
export function updateHubStatus(hubStatus: HubStatus): Action {
return {type: UPDATE_HUB_STATUS, payload: hubStatus};
}

export function updateInitialState(initialState: Object): Action {
Expand Down
15 changes: 11 additions & 4 deletions src/renderer/webapi/WebAPIClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,12 @@ export type JobResponseTransformer<JobResponse> = (any) => JobResponse;
* This is non JSON-RCP, which only allows for either the "response" or an "error" object.
*/
export interface WebAPIClient {
/**
* Test if the connection is open and active.
*/
readonly isOpen: boolean;
readonly url: string;

onOpen: (event) => void;
onClose: (event) => void;
onError: (event) => void;
Expand Down Expand Up @@ -142,16 +147,14 @@ class WebAPIClientImpl implements WebAPIClient {
onError: (event) => void;
onWarning: (event) => void;

readonly socket: WebSocketMin;
private readonly socket: WebSocketMin;
private currentMessageId = 0;
private activeJobs: JobImpl<any>[];
private isOpen: boolean;
private readonly activeJobs: JobImpl<any>[];

constructor(url: string, firstMessageId = 0, socket?: WebSocketMin) {
this.url = url;
this.currentMessageId = firstMessageId;
this.activeJobs = [];
this.isOpen = false;
this.socket = socket ? socket : new WebSocket(url);
this.socket.onopen = (event) => {
if (this.onOpen) {
Expand All @@ -174,6 +177,10 @@ class WebAPIClientImpl implements WebAPIClient {
}
}

get isOpen(): boolean {
return this.socket.readyState === WebSocket.OPEN;
}

call<JobResponse>(method: string,
params: Array<any> | Object,
onProgress?: (progress: JobProgress) => void,
Expand Down
10 changes: 10 additions & 0 deletions src/renderer/webapi/WebSocketMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
* @author Norman Fomferra
*/
export interface WebSocketMin {
readonly readyState: number;

onclose: (this: this, ev: CloseEvent) => any;
onerror: (this: this, ev: ErrorEvent) => any;
onmessage: (this: this, ev: MessageEvent) => any;
Expand Down Expand Up @@ -52,6 +54,7 @@ export class WebSocketMock implements WebSocketMin {
onclose: (this: this, ev: any) => any;
readonly messageLog: string[] = [];
readonly serviceObj: any;
readyState: number;

// <<<< WebSocketMin implementation
////////////////////////////////////////////
Expand All @@ -68,6 +71,7 @@ export class WebSocketMock implements WebSocketMin {
}
this.serviceObj = serviceObj;
this.asyncCalls = asyncCalls;
this.readyState = WebSocket.CONNECTING;
}

send(data: string) {
Expand All @@ -77,6 +81,7 @@ export class WebSocketMock implements WebSocketMin {

close(code?: number, reason?: string): void {
this.onclose({code, reason});
this.readyState = WebSocket.CLOSED;
}

emulateIncomingMessages(...messages: Object[]) {
Expand All @@ -95,14 +100,19 @@ export class WebSocketMock implements WebSocketMin {

emulateOpen(event) {
this.onopen(event);
this.readyState = WebSocket.OPEN;
}

emulateError(event) {
this.readyState = WebSocket.CLOSING;
this.onerror(event);
this.readyState = WebSocket.CLOSED;
}

emulateClose(event) {
this.readyState = WebSocket.CLOSING;
this.onclose(event);
this.readyState = WebSocket.CLOSED;
}

private maybeUseServiceObj(messageText) {
Expand Down

0 comments on commit 4c6a667

Please sign in to comment.