bamaer opened a new issue, #9005:
URL: https://github.com/apache/hop/issues/9005

   ### Apache Hop version?
   
   2.20.0-SNAPSHOT (current `main`/develop, commit b06f3588b4)
   
   ### Java version?
   
   OpenJDK 21.0.12.1
   
   ### Operating system
   
   Linux (x86_64)
   
   ### What happened?
   
   A plugin that does work in the `PipelineCompleted` extension point loses it 
when the process is `hop-run`: the extension point runs *after* the threads 
blocked in `Pipeline.waitUntilFinished()` are released, and `HopRun` exits the 
JVM as soon as it is released.
   
   In `Pipeline.fireExecutionFinishedListeners()`:
   
   ```java
   pipelineCompleted();                              // releases 
waitUntilFinished()
   ExtensionPointHandler.callExtensionPoint(..., PipelineCompleted.id, this);
   ```
   
   `Pipeline.pipelineCompleted()` sets the result and calls `notifyAll()` on 
the waiters. `HopRun.run()` is waiting there, prints `HopRun exit.` and calls 
`System.exit(0)` immediately, so the extension point never runs. The lineage 
hub flushes its queue exactly there (`LineageHubPipelineCompletedXp`), and its 
dispatcher is a daemon thread, so the whole queue dies with the JVM.
   
   Measured with the OpenLineage sink, a two-transform pipeline that takes 0.07 
s: **0 of 8 events arrive, in 12 of 12 `hop-run` runs.** Keeping the JVM alive 
with a 3 s `Delay` transform makes it deliver all 8 — i.e. the sample only 
works because it stays alive, not because the events get out.
   
   Two related orderings lose the tail even when the JVM survives:
   
   * **The last transform's `TransformFinished` is registered behind the 
pipeline's completion detector.** `handleTransform` adds the completion 
detection with `getTransformFinishedListeners().add(0, finishedListener)` and 
only then adds the listener that calls the `TransformFinished` extension point. 
The detector fires first, so the last transform's `FINISHED` event (and its 
I/O) is queued *after* the flush. Measured: with the reorder above plus a flush 
before `System.exit`, 11 of 12 runs delivered 8 of 8; moving the 
`TransformFinished` registration ahead of the detector made it 12 of 12.
   * **The `SingleThreaded` engine never announces its transforms.** 
`handleTransform`'s `case SingleThreaded` branch does nothing ("this needs to 
be handled by the pipeline executor"), and the executor never calls 
`TransformBeforeStart`/`TransformFinished`. That run configuration therefore 
emits only the pipeline's own events: 4 of the expected 8 measured, with no 
transform lifecycle at all.
   
   **Proposed fix** (a local patch exists, with three regression tests in 
`PipelineTest`; the engine suite is green):
   
   1. Call the `PipelineCompleted` extension point *before* releasing the 
waiters, and release them in a `finally` so a failing extension point can never 
deadlock a caller.
   2. Register the transform-finished extension point ahead of the completion 
detector, before the transform threads start.
   3. Register `TransformBeforeStart`/`TransformFinished` for the 
`SingleThreaded` run configuration as well.
   4. As belt and braces, flush the lineage hub once more in `HopRun` before 
`System.exit` (a no-op when lineage is disabled).
   
   Happy to open a PR if that is the preferred route; filed as a bug first 
because item 1 changes the order in which existing plugins see 
`PipelineCompleted` and `waitUntilFinished()`.
   
   ### Issue Priority
   
   High (a documented extension point is unreliable for every plugin that uses 
it, and the failure is silent)
   
   ### Issue Component
   
   Engine
   


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