Skip to content

Commit

Permalink
Decouple Acknowledgement (#1477)
Browse files Browse the repository at this point in the history
* Decouple Acknowledgement

* revert export
  • Loading branch information
dinhlongviolin1 authored Jul 5, 2024
1 parent e42f1c4 commit d11c2c1
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 48 deletions.
44 changes: 37 additions & 7 deletions frontend/taipy-gui/base/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import { Socket, io } from "socket.io-client";
import { DataManager, ModuleData } from "./dataManager";
import { initSocket } from "./socket";
import { TaipyWsAdapter, WsAdapter } from "./wsAdapter";
import { WsMessageType } from "./packaging/taipy-gui-base";

export type OnInitHandler = (taipyApp: TaipyApp) => void;
export type OnChangeHandler = (taipyApp: TaipyApp, encodedName: string, value: unknown) => void;
export type OnNotifyHandler = (taipyApp: TaipyApp, type: string, message: string) => void;
export type OnReloadHandler = (taipyApp: TaipyApp, removedChanges: ModuleData) => void;
export type OnWsStatusUpdate = (taipyApp: TaipyApp, messageQueue: string[]) => void;
type Route = [string, string];

export class TaipyApp {
Expand All @@ -19,6 +21,8 @@ export class TaipyApp {
_onChange: OnChangeHandler | undefined;
_onNotify: OnNotifyHandler | undefined;
_onReload: OnReloadHandler | undefined;
_onWsStatusUpdate: OnWsStatusUpdate | undefined;
_ackList: string[];
variableData: DataManager | undefined;
functionData: DataManager | undefined;
appId: string;
Expand All @@ -33,7 +37,7 @@ export class TaipyApp {
onInit: OnInitHandler | undefined = undefined,
onChange: OnChangeHandler | undefined = undefined,
path: string | undefined = undefined,
socket: Socket | undefined = undefined,
socket: Socket | undefined = undefined
) {
socket = socket || io("/", { autoConnect: false });
this.onInit = onInit;
Expand All @@ -48,6 +52,7 @@ export class TaipyApp {
this.path = path;
this.socket = socket;
this.wsAdapters = [new TaipyWsAdapter()];
this._ackList = [];
// Init socket io connection
initSocket(socket, this);
}
Expand Down Expand Up @@ -96,22 +101,43 @@ export class TaipyApp {
this._onReload = handler;
}

get onWsStatusUpdate() {
return this._onWsStatusUpdate;
}
set onWsStatusUpdate(handler: OnWsStatusUpdate | undefined) {
if (handler !== undefined && handler?.length !== 2) {
throw new Error("_onWsStatusUpdate() requires two parameters");
}
this._onWsStatusUpdate = handler;
}

// Utility methods
init() {
this.clientId = "";
this.context = "";
this.appId = "";
this.routes = undefined;
const id = getLocalStorageValue(TAIPY_CLIENT_ID, "");
sendWsMessage(this.socket, "ID", TAIPY_CLIENT_ID, id, id, undefined, false);
sendWsMessage(this.socket, "AID", "connect", "", id, undefined, false);
sendWsMessage(this.socket, "GR", "", "", id, undefined, false);
this.sendWsMessage("ID", TAIPY_CLIENT_ID, id);
this.sendWsMessage("AID", "connect", "");
this.sendWsMessage("GR", "", "");
if (id !== "") {
this.clientId = id;
this.updateContext(this.path);
}
}

sendWsMessage(type: WsMessageType, id: string, payload: unknown, context: string | undefined = undefined) {
if (context === undefined) {
context = this.context;
}
const ackId = sendWsMessage(this.socket, type, id, payload, this.clientId, context);
if (ackId) {
this._ackList.push(ackId);
this.onWsStatusUpdate && this.onWsStatusUpdate(this, this._ackList);
}
}

// Public methods
registerWsAdapter(wsAdapter: WsAdapter) {
this.wsAdapters.unshift(wsAdapter);
Expand Down Expand Up @@ -153,7 +179,7 @@ export class TaipyApp {
// This update will only send the request to Taipy Gui backend
// the actual update will be handled when the backend responds
update(encodedName: string, value: unknown) {
sendWsMessage(this.socket, "U", encodedName, { value: value }, this.clientId, this.context);
this.sendWsMessage("U", encodedName, { value: value });
}

getContext() {
Expand All @@ -164,12 +190,12 @@ export class TaipyApp {
if (!path || path === "") {
path = window.location.pathname.slice(1);
}
sendWsMessage(this.socket, "GMC", "get_module_context", { path: path || "/" }, this.clientId);
this.sendWsMessage("GMC", "get_module_context", { path: path || "/" });
}

trigger(actionName: string, triggerId: string, payload: Record<string, unknown> = {}) {
payload["action"] = actionName;
sendWsMessage(this.socket, "A", triggerId, payload, this.clientId, this.context);
this.sendWsMessage("A", triggerId, payload);
}

upload(encodedName: string, files: FileList, progressCallback: (val: number) => void) {
Expand All @@ -179,6 +205,10 @@ export class TaipyApp {
getPageMetadata() {
return this.metadata;
}

getWsStatus() {
return this._ackList;
}
}

export const createApp = (onInit?: OnInitHandler, onChange?: OnChangeHandler, path?: string, socket?: Socket) => {
Expand Down
2 changes: 0 additions & 2 deletions frontend/taipy-gui/base/src/exports.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { WsAdapter } from "./wsAdapter";
import { sendWsMessage } from "../../src/context/wsUtils";
// import { TaipyApp } from "./app";

export {
WsAdapter,
sendWsMessage,
// TaipyApp,
};
58 changes: 28 additions & 30 deletions frontend/taipy-gui/base/src/packaging/taipy-gui-base.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,44 @@ declare class DataManager {
getAllData(): Record<string, unknown>;
update(encodedName: string, value: unknown): void;
}
export type WsMessageType =
| "A"
| "U"
| "DU"
| "MU"
| "RU"
| "AL"
| "BL"
| "NA"
| "ID"
| "MS"
| "DF"
| "PR"
| "ACK"
| "GMC"
| "GDT"
| "AID"
| "GR";
export type OnInitHandler = (taipyApp: TaipyApp) => void;
export type OnChangeHandler = (taipyApp: TaipyApp, encodedName: string, value: unknown) => void;
export type OnNotifyHandler = (taipyApp: TaipyApp, type: string, message: string) => void;
export type OnReloadHandler = (taipyApp: TaipyApp, removedChanges: ModuleData) => void;
export type OnWsStatusUpdate = (taipyApp: TaipyApp, messageQueue: string[]) => void;
export type Route = [string, string];
export declare class TaipyApp {
socket: Socket;
_onInit: OnInitHandler | undefined;
_onChange: OnChangeHandler | undefined;
_onNotify: OnNotifyHandler | undefined;
_onReload: OnReloadHandler | undefined;
_onWsStatusUpdate: OnWsStatusUpdate | undefined;
_ackList: string[];
variableData: DataManager | undefined;
functionData: DataManager | undefined;
appId: string;
clientId: string;
context: string;
metadata: Record<string, unknown>;
path: string | undefined;
routes: Route[] | undefined;
wsAdapters: WsAdapter[];
Expand All @@ -53,7 +75,10 @@ export declare class TaipyApp {
set onNotify(handler: OnNotifyHandler | undefined);
get onReload(): OnReloadHandler | undefined;
set onReload(handler: OnReloadHandler | undefined);
get onWsStatusUpdate(): OnWsStatusUpdate | undefined;
set onWsStatusUpdate(handler: OnWsStatusUpdate | undefined);
init(): void;
sendWsMessage(type: WsMessageType | string, id: string, payload: unknown, context?: string | undefined): void;
registerWsAdapter(wsAdapter: WsAdapter): void;
getEncodedName(varName: string, module: string): string | undefined;
getName(encodedName: string): [string, string] | undefined;
Expand All @@ -68,45 +93,18 @@ export declare class TaipyApp {
updateContext(path?: string | undefined): void;
trigger(actionName: string, triggerId: string, payload?: Record<string, unknown>): void;
upload(encodedName: string, files: FileList, progressCallback: (val: number) => void): Promise<string>;
getPageMetadata(): any;
getPageMetadata(): Record<string, unknown>;
getWsStatus(): string[];
}
export type WsMessageType =
| "A"
| "U"
| "DU"
| "MU"
| "RU"
| "AL"
| "BL"
| "NA"
| "ID"
| "MS"
| "DF"
| "PR"
| "ACK"
| "GMC"
| "GDT"
| "AID"
| "GR";
export interface WsMessage {
type: WsMessageType | str;
type: WsMessageType | string;
name: string;
payload: Record<string, unknown> | unknown;
propagate: boolean;
client_id: string;
module_context: string;
ack_id?: string;
}
export declare const sendWsMessage: (
socket: Socket | undefined,
type: WsMessageType | str,
name: string,
payload: Record<string, unknown> | unknown,
id: string,
moduleContext?: string,
propagate?: boolean,
serverAck?: (val: unknown) => void
) => string;
export declare abstract class WsAdapter {
abstract supportedMessageTypes: string[];
abstract handleWsMessage(message: WsMessage, app: TaipyApp): boolean;
Expand Down
4 changes: 2 additions & 2 deletions frontend/taipy-gui/base/src/socket.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Socket } from "socket.io-client";
import { WsMessage, sendWsMessage } from "../../src/context/wsUtils";
import { WsMessage } from "../../src/context/wsUtils";
import { TaipyApp } from "./app";

export const initSocket = (socket: Socket, taipyApp: TaipyApp) => {
Expand All @@ -11,7 +11,7 @@ export const initSocket = (socket: Socket, taipyApp: TaipyApp) => {
// Send a request to get App ID to verify that the app has not been reloaded
socket.io.on("reconnect", () => {
console.log("WebSocket reconnected");
sendWsMessage(socket, "AID", "reconnect", taipyApp.appId, taipyApp.clientId, taipyApp.context);
taipyApp.sendWsMessage("AID", "reconnect", taipyApp.appId);
});
// try to reconnect on connect_error
socket.on("connect_error", (err) => {
Expand Down
10 changes: 7 additions & 3 deletions frontend/taipy-gui/base/src/wsAdapter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import merge from "lodash/merge";
import { TaipyApp } from "./app";
import { IdMessage, storeClientId } from "../../src/context/utils";
import { WsMessage, sendWsMessage } from "../../src/context/wsUtils";
import { WsMessage } from "../../src/context/wsUtils";
import { DataManager, ModuleData } from "./dataManager";

export abstract class WsAdapter {
Expand All @@ -25,7 +25,7 @@ export class TaipyWsAdapter extends WsAdapter {
initWsMessageTypes: string[];
constructor() {
super();
this.supportedMessageTypes = ["MU", "ID", "GMC", "GDT", "AID", "GR", "AL"];
this.supportedMessageTypes = ["MU", "ID", "GMC", "GDT", "AID", "GR", "AL", "ACK"];
this.initWsMessageTypes = ["ID", "AID", "GMC"];
}
handleWsMessage(message: WsMessage, taipyApp: TaipyApp): boolean {
Expand Down Expand Up @@ -81,6 +81,10 @@ export class TaipyWsAdapter extends WsAdapter {
} else if (message.type === "AL" && taipyApp.onNotify) {
const payload = message as AlertMessage;
taipyApp.onNotify(taipyApp, payload.atype, payload.message);
} else if (message.type === "ACK") {
const {id} = message as unknown as Record<string, string>;
taipyApp._ackList = taipyApp._ackList.filter((v) => v !== id);
taipyApp.onWsStatusUpdate && taipyApp.onWsStatusUpdate(taipyApp, taipyApp._ackList);
}
this.postWsMessageProcessing(message, taipyApp);
return true;
Expand All @@ -96,7 +100,7 @@ export class TaipyWsAdapter extends WsAdapter {
taipyApp.context !== "" &&
taipyApp.routes !== undefined
) {
sendWsMessage(taipyApp.socket, "GDT", "get_data_tree", {}, taipyApp.clientId, taipyApp.context);
taipyApp.sendWsMessage("GDT", "get_data_tree", {});
}
}
}
12 changes: 8 additions & 4 deletions taipy/gui/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -1133,7 +1133,8 @@ def __handle_ws_get_module_context(self, payload: t.Any):
{
"type": _WsType.GET_MODULE_CONTEXT.value,
"payload": {"context": mc, "metadata": meta_return},
}
},
send_back_only=True,
)

def __get_variable_tree(self, data: t.Dict[str, t.Any]):
Expand Down Expand Up @@ -1177,7 +1178,8 @@ def __handle_ws_get_data_tree(self):
"variable": self.__get_variable_tree(data),
"function": self.__get_variable_tree(function_data),
},
}
},
send_back_only=True,
)

def __handle_ws_app_id(self, message: t.Any):
Expand All @@ -1192,7 +1194,8 @@ def __handle_ws_app_id(self, message: t.Any):
{
"type": _WsType.APP_ID.value,
"payload": {"name": name, "id": app_id},
}
},
send_back_only=True,
)

def __handle_ws_get_routes(self):
Expand All @@ -1210,7 +1213,8 @@ def __handle_ws_get_routes(self):
{
"type": _WsType.GET_ROUTES.value,
"payload": routes,
}
},
send_back_only=True,
)

def __send_ws(self, payload: dict, allow_grouping=True, send_back_only=False) -> None:
Expand Down

0 comments on commit d11c2c1

Please sign in to comment.