From e3d94b22b7f8dbf78d5b7fbf8d11b6d35aa1ed3d Mon Sep 17 00:00:00 2001 From: heswell Date: Thu, 23 Nov 2023 14:38:18 +0000 Subject: [PATCH] fix basket disable enable (#1003) --- .../packages/vuu-data/src/inlined-worker.js | 33 ++-- .../vuu-data/src/remote-data-source.ts | 7 +- .../vuu-data/src/server-proxy/server-proxy.ts | 35 ++--- .../vuu-data/src/server-proxy/viewport.ts | 4 +- .../vuu-data/test/server-proxy.test.ts | 144 ++++++++++++++++++ .../src/useBasketTrading.tsx | 33 ++-- 6 files changed, 193 insertions(+), 63 deletions(-) diff --git a/vuu-ui/packages/vuu-data/src/inlined-worker.js b/vuu-ui/packages/vuu-data/src/inlined-worker.js index 4073fe937..490689184 100644 --- a/vuu-ui/packages/vuu-data/src/inlined-worker.js +++ b/vuu-ui/packages/vuu-data/src/inlined-worker.js @@ -1131,7 +1131,9 @@ var Viewport = class { const { clientViewportId, pendingOperations } = this; const pendingOperation = pendingOperations.get(requestId); if (!pendingOperation) { - error2("no matching operation found to complete"); + error2( + \`no matching operation found to complete for requestId \${requestId}\` + ); return; } const { type } = pendingOperation; @@ -1902,6 +1904,7 @@ var ServerProxy = class { viewport.suspendTimer = null; } const [size, rows] = viewport.resume(); + debug4 == null ? void 0 : debug4(\`resumeViewport size \${size}, \${rows.length} rows sent to client\`); this.postMessageToClient({ clientViewportId: viewport.clientViewportId, mode: "batch", @@ -2209,26 +2212,14 @@ var ServerProxy = class { const response = viewport.completeOperation(requestId); if (response) { this.postMessageToClient(response); - const rows = viewport.currentData(); - debugEnabled4 && debug4( - \`Enable Response (ServerProxy to Client): \${JSON.stringify( - response - )}\` - ); - if (viewport.size === 0) { - debugEnabled4 && debug4(\`Viewport Enabled but size 0, resend to server\`); - } else { - this.postMessageToClient({ - clientViewportId: viewport.clientViewportId, - mode: "batch", - rows, - size: viewport.size, - type: "viewport-update" - }); - debugEnabled4 && debug4( - \`Enable Response (ServerProxy to Client): send size \${viewport.size} \${rows.length} rows from cache\` - ); - } + const [size, rows] = viewport.resume(); + this.postMessageToClient({ + clientViewportId: viewport.clientViewportId, + mode: "batch", + rows, + size, + type: "viewport-update" + }); } } } diff --git a/vuu-ui/packages/vuu-data/src/remote-data-source.ts b/vuu-ui/packages/vuu-data/src/remote-data-source.ts index 476972d97..fb598fd04 100644 --- a/vuu-ui/packages/vuu-data/src/remote-data-source.ts +++ b/vuu-ui/packages/vuu-data/src/remote-data-source.ts @@ -131,6 +131,10 @@ export class RemoteDataSource }: SubscribeProps, callback: SubscribeCallback ) { + if (this.#status === "disabled" || this.#status === "disabling") { + this.enable(callback); + return; + } this.clientCallback = callback; if (aggregations || columns || filter || groupBy || sort) { this.#config = { @@ -152,11 +156,10 @@ export class RemoteDataSource if ( this.#status !== "initialising" && - this.#status !== "unsubscribed" && + this.#status !== "unsubscribed" // We can subscribe to a disabled dataSource. No request will be // sent to server to create a new VP, just to enable the existing one. // The current subscribing client becomes the subscription owner - this.#status !== "disabled" ) { return; } diff --git a/vuu-ui/packages/vuu-data/src/server-proxy/server-proxy.ts b/vuu-ui/packages/vuu-data/src/server-proxy/server-proxy.ts index bb12b9cb2..5382233bd 100644 --- a/vuu-ui/packages/vuu-data/src/server-proxy/server-proxy.ts +++ b/vuu-ui/packages/vuu-data/src/server-proxy/server-proxy.ts @@ -446,6 +446,7 @@ export class ServerProxy { viewport.suspendTimer = null; } const [size, rows] = viewport.resume(); + debug?.(`resumeViewport size ${size}, ${rows.length} rows sent to client`); this.postMessageToClient({ clientViewportId: viewport.clientViewportId, mode: "batch", @@ -810,31 +811,15 @@ export class ServerProxy { if (viewport) { const response = viewport.completeOperation(requestId); if (response) { - this.postMessageToClient(response as DataSourceEnabledMessage); - const rows = viewport.currentData(); - debugEnabled && - debug( - `Enable Response (ServerProxy to Client): ${JSON.stringify( - response - )}` - ); - - if (viewport.size === 0) { - debugEnabled && - debug(`Viewport Enabled but size 0, resend to server`); - } else { - this.postMessageToClient({ - clientViewportId: viewport.clientViewportId, - mode: "batch", - rows, - size: viewport.size, - type: "viewport-update", - }); - debugEnabled && - debug( - `Enable Response (ServerProxy to Client): send size ${viewport.size} ${rows.length} rows from cache` - ); - } + this.postMessageToClient(response); + const [size, rows] = viewport.resume(); + this.postMessageToClient({ + clientViewportId: viewport.clientViewportId, + mode: "batch", + rows, + size, + type: "viewport-update", + }); } } } diff --git a/vuu-ui/packages/vuu-data/src/server-proxy/viewport.ts b/vuu-ui/packages/vuu-data/src/server-proxy/viewport.ts index b672910cf..4cb9a6465 100644 --- a/vuu-ui/packages/vuu-data/src/server-proxy/viewport.ts +++ b/vuu-ui/packages/vuu-data/src/server-proxy/viewport.ts @@ -341,7 +341,9 @@ export class Viewport { const { clientViewportId, pendingOperations } = this; const pendingOperation = pendingOperations.get(requestId); if (!pendingOperation) { - error("no matching operation found to complete"); + error( + `no matching operation found to complete for requestId ${requestId}` + ); return; } const { type } = pendingOperation; diff --git a/vuu-ui/packages/vuu-data/test/server-proxy.test.ts b/vuu-ui/packages/vuu-data/test/server-proxy.test.ts index 152b8d13e..050f0e755 100644 --- a/vuu-ui/packages/vuu-data/test/server-proxy.test.ts +++ b/vuu-ui/packages/vuu-data/test/server-proxy.test.ts @@ -3531,4 +3531,148 @@ describe("ServerProxy", () => { }); }); }); + + describe("disable and enable", () => { + it("disable sends message to server", async () => { + const [serverProxy, , connection] = await createFixtures(); + connection.send.mockClear(); + TEST_setRequestId(1); + serverProxy.handleMessageFromClient({ + type: "disable", + viewport: "client-vp-1", + }); + + // viewport isn't disabled until requesty ACKED + expect(serverProxy["viewports"].get("server-vp-1")?.disabled).toBe(false); + + expect(connection.send).toHaveBeenCalledTimes(1); + expect(connection.send).toHaveBeenCalledWith({ + body: { + viewPortId: "server-vp-1", + type: "DISABLE_VP", + }, + module: "CORE", + requestId: "1", + sessionId: "dsdsd", + token: "test", + user: "user", + }); + }); + + it("viewport is disabled when disable request is ACKed", async () => { + const [serverProxy, , connection] = await createFixtures(); + connection.send.mockClear(); + TEST_setRequestId(1); + serverProxy.handleMessageFromClient({ + type: "disable", + viewport: "client-vp-1", + }); + + serverProxy.handleMessageFromServer({ + ...COMMON_ATTRS, + requestId: "1", + body: { + type: "DISABLE_VP_SUCCESS", + viewPortId: "server-vp-1", + }, + }); + + expect(serverProxy["viewports"].get("server-vp-1")?.disabled).toBe(true); + }); + + it("viewport is enabled when enable request is ACKed", async () => { + const [serverProxy, , connection] = await createFixtures(); + connection.send.mockClear(); + TEST_setRequestId(1); + serverProxy.handleMessageFromClient({ + type: "disable", + viewport: "client-vp-1", + }); + serverProxy.handleMessageFromServer({ + ...COMMON_ATTRS, + requestId: "1", + body: { + type: "DISABLE_VP_SUCCESS", + viewPortId: "server-vp-1", + }, + }); + + TEST_setRequestId(1); + serverProxy.handleMessageFromClient({ + type: "enable", + viewport: "client-vp-1", + }); + expect(serverProxy["viewports"].get("server-vp-1")?.disabled).toBe(true); + + serverProxy.handleMessageFromServer({ + ...COMMON_ATTRS, + requestId: "1", + body: { + type: "ENABLE_VP_SUCCESS", + viewPortId: "server-vp-1", + }, + }); + expect(serverProxy["viewports"].get("server-vp-1")?.disabled).toBe(false); + }); + + it("full data update is sent to client once enable is ACKed", async () => { + const [serverProxy, postMessageToClient] = await createFixtures(); + + serverProxy.handleMessageFromServer({ + ...COMMON_ATTRS, + requestId: "1", + body: { + ...COMMON_TABLE_ROW_ATTRS, + rows: [ + sizeRow("server-vp-1", 100), + ...createTableRows("server-vp-1", 0, 10), + ], + }, + }); + + postMessageToClient.mockClear(); + TEST_setRequestId(1); + // prettier-ignore + serverProxy.handleMessageFromClient({type: "disable", viewport: "client-vp-1" }); + serverProxy.handleMessageFromServer({ + ...COMMON_ATTRS, + requestId: "1", + body: { + type: "DISABLE_VP_SUCCESS", + viewPortId: "server-vp-1", + }, + }); + // prettier-ignore + serverProxy.handleMessageFromClient({ type: "enable", viewport: "client-vp-1" }); + serverProxy.handleMessageFromServer({ + ...COMMON_ATTRS, + requestId: "2", + body: { + type: "ENABLE_VP_SUCCESS", + viewPortId: "server-vp-1", + }, + }); + + expect(postMessageToClient).toHaveBeenCalledTimes(3); + expect(postMessageToClient).toHaveBeenLastCalledWith({ + clientViewportId: "client-vp-1", + mode: "batch", + // prettier-ignore + rows: [ + [0,0,true,false,0,0,'key-00', 0,'key-00', 'name 00',1000,true], + [1,1,true,false,0,0,"key-01",0,"key-01","name 01",1001,true], + [2,2,true,false,0,0,"key-02",0,"key-02","name 02",1002,true], + [3,3,true,false,0,0,"key-03",0,"key-03","name 03",1003,true], + [4,4,true,false,0,0,"key-04",0,"key-04","name 04",1004,true], + [5,5,true,false,0,0,"key-05",0,"key-05","name 05",1005,true], + [6,6,true,false,0,0,"key-06",0,"key-06","name 06",1006,true], + [7,7,true,false,0,0,"key-07",0,"key-07","name 07",1007,true], + [8,8,true,false,0,0,"key-08",0,"key-08","name 08",1008,true], + [9,9,true,false,0,0,"key-09",0,"key-09","name 09",1009,true] + ], + size: 100, + type: "viewport-update", + }); + }); + }); }); diff --git a/vuu-ui/sample-apps/feature-basket-trading/src/useBasketTrading.tsx b/vuu-ui/sample-apps/feature-basket-trading/src/useBasketTrading.tsx index 3b80aa11e..d2a4b5f21 100644 --- a/vuu-ui/sample-apps/feature-basket-trading/src/useBasketTrading.tsx +++ b/vuu-ui/sample-apps/feature-basket-trading/src/useBasketTrading.tsx @@ -11,6 +11,7 @@ import { useBasketContextMenus } from "./useBasketContextMenus"; import { useBasketTradingDataSources } from "./useBasketTradingDatasources"; import { BasketTradingFeatureProps } from "./VuuBasketTradingFeature"; import { VuuDataRow, VuuDataRowDto } from "packages/vuu-protocol-types"; +import { SubscribeCallback } from "packages/vuu-data/src"; export class Basket { basketId: string; @@ -104,33 +105,37 @@ export const useBasketTrading = ({ () => buildColumnMap(dataSourceBasketTradingControl.columns), [dataSourceBasketTradingControl.columns] ); - const columnMapInstrument = useMemo( - () => buildColumnMap(dataSourceInstruments.columns), - [dataSourceInstruments.columns] + + const handleMessageFromBasketTradingControl = useCallback( + (message) => { + if (message.type === "viewport-update") { + if (message.size) { + setBasketCount(message.size); + } + if (message.rows && message.rows.length > 0) { + setBasket(new Basket(message.rows[0], columnMapBasketTrading)); + } + } + }, + [columnMapBasketTrading] ); useMemo(() => { + console.log( + `subscribe to BT COntrol ${dataSourceBasketTradingControl.status}` + ); dataSourceBasketTradingControl.subscribe( { range: { from: 0, to: 1 }, }, - (message) => { - if (message.type === "viewport-update") { - if (message.size) { - setBasketCount(message.size); - } - if (message.rows && message.rows.length > 0) { - setBasket(new Basket(message.rows[0], columnMapBasketTrading)); - } - } - } + handleMessageFromBasketTradingControl ); // TEMP server is notsending TABLE_ROWS if size is zero setTimeout(() => { setBasketCount((count) => (count === -1 ? 0 : count)); }, 800); - }, [columnMapBasketTrading, dataSourceBasketTradingControl]); + }, [dataSourceBasketTradingControl, handleMessageFromBasketTradingControl]); const handleCloseNewBasketPanel = useCallback(() => { setBasketState((state) => ({