aicam opened a new issue, #6420:
URL: https://github.com/apache/texera/issues/6420

   ## Bug
   
   `JointGraphWrapper.getElementPositionChangeEvent()` throws inside its 
`map()` operator when it can't find bookkeeping for an element:
   
   
https://github.com/apache/texera/blob/master/frontend/src/app/workspace/service/workflow-graph/model/joint-graph-wrapper.ts#L304-L311
   
   ```ts
   return fromEvent<JointPositionChangeEvent>(this.jointGraph, 
"change:position").pipe(
     map(e => {
       const elementID = e[0].id.toString();
       const oldPosition = this.elementPositions.get(elementID);
       ...
       if (!oldPosition) {
         throw new Error(`internal error: cannot find element position for 
${elementID}`);
       }
   ```
   
   In RxJS, an error that reaches a subscriber **permanently unsubscribes the 
pipeline**. The main consumer, 
`WorkflowActionService.handleJointElementDrag()`, subscribes exactly **once per 
tab** at service construction (`workflow-action.service.ts:124` → `:856`), and 
it is the only path that writes local drags into 
`sharedModel.elementPositionMap` for shared editing.
   
   So a single `change:position` event for an element missing from 
`elementPositions` (e.g. a position change delivered during a window where the 
element was added/removed by another code path, undo/redo, or a remote peer) 
kills the stream, and from then on **that tab silently stops broadcasting 
operator positions forever** — while operator/link add/delete keep syncing, 
because those are separate streams. Local dragging still works, so the affected 
user has no signal anything is wrong; the symptom is only visible to *other* 
collaborators ("new operators show up but moves don't"). A page reload rebuilds 
the subscription and "fixes" it.
   
   ## Observed
   
   Hit this while testing #6240 on a local minikube deployment with two 
browsers on the same workflow: one tab's position sync stopped while adds/links 
kept flowing; the receive path was verified healthy (positions injected into 
`elementPositionMap` by an external Yjs client rendered in both tabs), and a 
reload restored broadcast. Fresh sessions driven by Playwright always synced 
10/10 position updates, consistent with a long-lived subscription dying rather 
than a logic bug in the happy path.
   
   ## Suggested fix
   
   Make the stream survive bad events instead of dying, e.g. filter out unknown 
elements instead of throwing:
   
   ```ts
   map(...) // may return undefined for unknown elementID
   filter(x => x !== undefined)
   ```
   
   or wrap consumers with `catchError`/`retry`. Same consideration applies to 
the other subscriber at `workflow-action.service.ts:691` (undo/redo debounce 
merge) and any other stream that throws inside an operator on a once-per-tab 
subscription.


-- 
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]

Reply via email to