aicam opened a new pull request, #6240: URL: https://github.com/apache/texera/pull/6240
### What changes were proposed in this PR? Fixes two distinct `y-websocket` (`/rtc`) connection leaks in the shared-editing code path. Both live on `SharedModel` → `WebsocketProvider`, and together they let the number of open realtime connections grow far out of proportion to the number of users until the shared-editing connection cap is exhausted and collaborative cursors/awareness stop syncing. **Leak B — throwaway validation graph opens a socket per edit (dominant).** On every operator/link/property edit, `WorkflowCompilingService` builds a throwaway `WorkflowGraph` via `ValidationWorkflowService.getValidTexeraGraph()` just to produce a logical plan for compilation. `WorkflowGraph`'s constructor **unconditionally** creates a `SharedModel`, which **unconditionally** opens a new auto-connecting `/rtc` WebSocket in a random room. That graph is read once and never destroyed, so each edit leaks a socket that reconnects forever. A single user editing a workflow accumulates dozens of permanent sockets. Fix: thread an `enableSharedEditing` flag from `WorkflowGraph` into `SharedModel`. When `false`, `SharedModel` skips the `WebsocketProvider` entirely and uses a standalone `Awareness` so downstream reads of `awareness`/`clientId` keep working. `ValidationWorkflowService.getValidTexeraGraph()` now passes `false`, so validation/compilation graphs never touch the network. **Leak A — incomplete provider teardown (per-navigation).** `SharedModel.destroy()` called `wsProvider.disconnect()` (and only when the socket happened to be OPEN). In `[email protected]`, `disconnect()` does not clear the provider's `_checkInterval`/`_resyncInterval` reconnect timers, so the provider is never garbage-collected and, if it was mid-reconnect at destroy time (common during workflow switches), keeps re-opening a zombie socket for the life of the tab. Fix: call `wsProvider.destroy()` unconditionally, which clears those timers, removes the `beforeunload` handler, broadcasts awareness removal (peers drop our cursor), and closes the socket. **Supporting changes.** `wsProvider` is now optional (`WebsocketProvider | undefined`), so its remaining access sites in `WorkflowActionService` (`setTempWorkflow` / `resetTempWorkflow`) use `?.`, and the `mock-workflow-plan.ts` fixtures pass `enableSharedEditing = false` so unit tests open no sockets. Behavior for the real collaborative graph is unchanged: it still constructs a `WebsocketProvider` exactly as before. Files changed: - `frontend/src/app/workspace/service/workflow-graph/model/shared-model.ts` — optional/local-mode provider; correct `destroy()`. - `frontend/src/app/workspace/service/workflow-graph/model/workflow-graph.ts` — thread `enableSharedEditing`. - `frontend/src/app/workspace/service/validation/validation-workflow.service.ts` — pass `false` for the throwaway graph. - `frontend/src/app/workspace/service/workflow-graph/model/workflow-action.service.ts` — `wsProvider?.` null-safety. - `frontend/src/app/workspace/service/execute-workflow/mock-workflow-plan.ts` — fixtures open no sockets. ### Any related issues, documentation, discussions? Fixes #6239. ### How was this PR tested? Existing frontend unit tests continue to pass; the `mock-workflow-plan.ts` fixtures were updated to construct their graphs local-only so tests no longer open real `/rtc` sockets. Manual verification, client-side (browser DevTools → Network → **WS** filter): 1. Open a workflow → exactly **one** `/rtc` WebSocket (unchanged). 2. Add/delete operators, edit properties, add/remove links repeatedly → the count stays at **one** (before this change, a new socket appeared on every edit and kept reconnecting). 3. Switch workflow A → B → the old socket closes and one new socket opens (count stays 1). 4. Navigate to the dashboard / close the tab → the socket closes (count → 0), with no lingering reconnects. The same behavior is observable server-side by counting established connections to the y-websocket server while a single user edits: after this change the count stays flat (≈ number of open collaborative tabs) and drops when tabs close, instead of climbing with every edit. ### Was this PR authored or co-authored using generative AI tooling? Generated-by: Claude Code (Claude Opus 4.8) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
