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]

Reply via email to