He-Pin opened a new issue, #3729:
URL: https://github.com/apache/pekko/issues/3729
### Motivation
The unchanged `TcpSpec` case "TLS client and server convenience methods with
SSLEngine setup should allow for TLS" can return `hell` instead of `hello` with
`graph-stage` selected. Its server echoes characters through `takeWhile(_ !=
'\n')` and the four-argument `bindAndHandleWithTls` overload uses the default
closing policy.
### Modification
Investigate the ordering between handler cancellation and delivery of the
last echoed byte to TLS. Preserve the complete-response assertion and establish
the intended test contract with a focused, deterministic regression. The
existing tests and policies were not changed during this investigation.
Reproduce on OpenJDK 25.0.2:
```sh
rtk sbt 'show stream-tests/Test/fork'
rtk sbt \
'set (LocalProject("stream-tests") / Test / javaOptions) +=
"-Dpekko.stream.materializer.tls.engine=graph-stage"' \
'stream-tests/Test/testOnly org.apache.pekko.stream.io.TcpSpec -- -z
"allow for TLS"'
```
Repeat because the failure is intermittent. For the default engine, omit the
`set` command.
### Result
Expected by the existing assertion: `hello`. Observed on failure: `hell`
(`TcpSpec.scala:946`).
Temporary server-side logging after `UserInputSlot.onPush` enqueues an
element, and at plaintext-output cancellation, showed this order in every
diagnosed failure on both revisions:
```text
accept h
accept e
accept l
accept l
cancel plaintext output
accept o
client result: hell
```
Thus `o` had not been accepted when cancellation was observed. It
subsequently reached `onPush`; the trace does not identify the exact upstream
buffer involved. This is separate from #3727's guarantee for plaintext already
accepted at cancellation, and reproducing it on #3727 does not invalidate that
fix.
### Tests
2026-10-29, macOS arm64 (12 CPUs), OpenJDK 25.0.2, Scala 2.13.18, TLS 1.3:
| Revision | Engine | Runs without diagnostics | Failures | Diagnostic runs
| Diagnostic failures |
| --- | --- | ---: | ---: | ---: | ---: |
| `a55a008fdf` | legacy-actor | 20 | 0 (0%) | 20 | 0 (0%) |
| `a55a008fdf` | graph-stage | 20 | 8 (40%) | 20 | 11 (55%) |
| `205155160a` | legacy-actor | 20 | 0 (0%) | 20 | 0 (0%) |
| `205155160a` | graph-stage | 20 | 13 (65%) | 20 | 12 (60%) |
Repeated measurements used the unchanged ScalaTest case in fresh JVMs with
sbt-exported classpath and test JVM options, after confirming `fork = true`.
GraphStage was selected explicitly with
`-Dpekko.stream.materializer.tls.engine=graph-stage`. A direct sbt run on main
also reproduced `hell`.
All diagnosed GraphStage successes accepted `hello` before cancellation.
Legacy receipt and `ChoppingBlock.chopInto` logs contained `hello`. The
diagnostic modifications were removed and are not proposed for commit.
The workstation was shared, with no synthetic stress workload introduced.
One-minute load ranges were 5.76–6.72 for the main baseline, 19.40–34.44 for
the PR baseline, 6.88–8.38 for main diagnostics, and 7.85–9.26 for PR
diagnostics. The counts do not establish relative failure probabilities or
results on other JDKs.
### References
Refs #2860 and #3727. This follow-up concerns the TcpSpec
cancellation/delivery contract, not #3728's buffer allocation/growth work.
--
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]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]