The GitHub Actions job "Required Checks" on texera.git/main has failed.
Run started by GitHub user github-merge-queue[bot] (triggered by 
github-merge-queue[bot]).

Head commit for run:
f642c183dc5461f31b84f6bd37dc12e917ca3fdd / Xinyuan Lin <[email protected]>
fix(amber): release the reconfiguration service's engine callback on teardown 
(#7823)

### What changes were proposed in this PR?

`ExecutionReconfigurationService.registerWorkerCompletionCallback`
discarded the `Disposable` returned by `client.registerCallback`, so its
engine callback outlived the service. It now hands it to
`addSubscription(...)`, matching `registerCompletionDiffHandler`
directly below it.

It was the only `registerCallback` site in
`org.apache.texera.web.service` not doing this:

| File | sites | wrapped |
|---|---|---|
| `ExecutionStatsService.scala` | 5 | yes |
| `ExecutionResultService.scala` | 3 | yes |
| `ExecutionConsoleService.scala` | 2 | yes |
| `ExecutionRuntimeService.scala` | 1 | yes |
| `ExecutionReconfigurationService.scala` | 1 | **no** |

### Why this actually leaks, rather than being tidied up by something
else

The teardown path is live: `WorkflowExecutionService.unsubscribeAll`
(`WorkflowExecutionService.scala:185`) calls
`executionReconfigurationService.unsubscribeAll()`, which released every
other subscription but not this one.

And `client.shutdown()` is not an alternative release — it flips
`isActive` and poison-pills the `ClientActor`, but never touches
`registeredObservables`, which is written only in `registerCallback` and
never cleared. The `PublishSubject` chain therefore keeps the subscriber
closure, and through it the service, its `ExecutionStateStore` and its
`Workflow`, for as long as the `AmberClient` is reachable — which
`WorkflowExecutionService.client` guarantees.

### The fix is pinned

New test: `"the worker completion callback" should "release the engine
subscription once the service is unsubscribed"`. Verified with the
production file reverted and restored:

| | production reverted | with fix |
|---|---|---|
| `ExecutionReconfigurationServiceSpec` | **13 passed, 1 failed** | **14
passed** |

The before-state failure is the right one — `ArrayBuffer() did not
contain element class …UpdateExecutorCompleted`, i.e. the disposable was
never disposed because it was never registered.

Two additions to the existing `TestAmberClient` double were needed, and
the reasons are worth stating: an explicit `disposedCallbacks` record,
because disposal-removal from the `callbacks` map alone is
indistinguishable from "never registered" or "cleared by `reset`"; and a
`fireIfRegistered` helper, because the strict `fire` calls `fail(...)`
when nothing is registered and so cannot express "a late event is
inert".

### Two comments were rewritten, not just tests added

Both would otherwise have contradicted the code:

1. `TestAmberClient.registerCallback`'s scaladoc said production
"currently DISCARDS it" and that "no test below fires an engine event
after `unsubscribeAll`, so the suite neither depends on the leak nor
breaks when it is fixed." Both clauses are now false.
2. The routing comment in `"stop announcing completions once the service
is unsubscribed"` called the engine callback an "unrelated, currently
broken, seam". The routing decision — drive that test through
`onWorkerReconfigured` rather than the engine event — is still right and
unchanged, but re-justified: the two are separate subscriptions, so
routing through the engine event would leave an empty batch explainable
by either one being released. That test's assertion is untouched, so it
stays agnostic exactly as #7692 intended.

### Verification

- `ExecutionReconfigurationServiceSpec` 14/14.
- Dependents and neighbours: `ExecutionRuntimeServiceSpec`,
`WorkflowExecutionServiceSpec`, `ExecutionStatsServiceSpec`,
`ExecutionConsoleServiceSpec`, `WorkflowWebsocketResourceSpec`,
`TexeraWebSocketEventSpec` — **59/59 across 6 suites, 0 aborted**.
- `scalafmtCheck`, `Test/scalafmtCheck`, `scalafixAll --check` all pass.
(The one scalafix warning is a pre-existing `// scalafix:ok` in
`OutputManagerSpec`, unrelated.)

### One thing deliberately left alone

The suite still carries an assertion recorded as *observed, not
endorsed*: an N-worker operator fires N `ModifyLogicCompletedEvent`s,
which contradicts `registerCompletionDiffHandler`'s own comment claiming
the frontend is notified once **all** workers finish. That is a separate
defect with its own decision to make, so this PR does not touch it.

### Any related issues, documentation, discussions?

Closes #7822

### How was this PR tested?

```
STORAGE_ICEBERG_CATALOG_TYPE=postgres sbt "WorkflowExecutionService/testOnly 
org.apache.texera.web.service.ExecutionReconfigurationServiceSpec"
```

```
[info] Total number of tests run: 14
[info] Tests: succeeded 14, failed 0, canceled 0, ignored 0, pending 0
```

### Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Opus 5)

Report URL: https://github.com/apache/texera/actions/runs/35551729521

With regards,
GitHub Actions via GitBox

Reply via email to