kenhuuu opened a new pull request, #3457:
URL: https://github.com/apache/tinkerpop/pull/3457
## Why
Response writing in the 4.x HTTP endpoint was coordinated through three
uncoordinated state holders (`Context.requestState`, `Context.startedResponse`,
`StateKey.HTTP_RESPONSE_SENT`) touched by two threads (eval worker + timeout
scheduler) with no happens-before relationship. The non-atomic check-then-act
guards allowed a **double-response race under timeout** and an **unterminated
chunked stream** (which hangs the client and poisons the
keep-alive channel). Write logic was also scattered across `makeChunk` and
`HttpHandlerUtil`, so "who writes, in what order" was an unwritten contract.
## What changed
A single per-request `HttpResponseCoordinator` is now the sole owner of
response writes, guarded by one monitor with a 3-state machine (`NOT_STARTED →
STREAMING → COMPLETED`). This makes the key invariant — **exactly one
well-formed, terminated response** — true by construction:
- Both the eval task and the timeout task enter the same monitor; whichever
reaches `COMPLETED` first wins, the other no-ops. No more check-then-act gap.
- `complete()` is idempotent and called from a `finally`, so the terminal
chunk is always written.
The three state holders, `makeChunk`, and the `HttpHandlerUtil` write
helpers are removed/absorbed (`sendError` stays for the pre-evaluation
rejection path). Backpressure stays outside the lock, so there's no deadlock
surface.
This is a **pure internal refactor**: wire output is byte-identical, no
public/driver API or status-code changes.
## Second fix: enqueued transactions must return errors
Validating the refactor surfaced an intermittent CI hang. Transactions run
on a single-threaded executor; a request queued behind a `commit` was silently
discarded by `shutdownNow()`, so its client never got a response. Fixed in
`UnmanagedTransaction.close` by using a graceful `shutdown()` (queued tasks run
and return 404 instead of vanishing) and removing the transaction from the
manager *before* shutdown so those tasks fail fast without mutating a closed
transaction. The ordering is documented as load-bearing.
NOTE: No documentation or CHANGELOG as this is just a refactoring.
VOTE+1
<!--
Thanks for contributing! Reminders:
+ TARGET the earliest branch where you want the change
3.7-dev -> 3.7.7 (non-breaking only)
3.8-dev -> 3.8.2 (non-breaking only)
master -> 4.0.0
+ Committers will MERGE the PR forward to newer versions
+ ADD entry to the CHANGELOG.asciidoc for the targeted version
Do not reference a JIRA number there
+ ADD JIRA number to title and link in description
+ PRs requires 3 +1s from committers OR
1 +1 and 7 day wait to merge.
+ MORE details: https://s.apache.org/rtnal
-->
--
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]