Aias00 opened a new pull request, #3531:
URL: https://github.com/apache/dubbo-go/pull/3531

   ## What
   
   `ExchangeClient.AsyncRequest` leaked a `PendingResponse` and never invoked 
the `AsyncCallback` when no reply arrived (e.g. the connection dropped before 
the server responded).
   
   ## Why
   
   ```go
   // remoting/exchange_client.go AsyncRequest (before)
   rsp := NewPendingResponse(request.ID)
   rsp.Callback = callback
   AddPendingResponse(rsp)
   err := client.client.Request(request, timeout, rsp)
   if err != nil {
       RemovePendingResponse(SequenceType(request.ID))   // only the 
write-error path cleans up
       result.Err = err
       return err
   }
   result.Rest = rsp.response
   return nil   // no timeout enforcement; no removal/callback on no-reply
   ```
   
   The async path returns immediately (getty returns immediately for callback 
requests, so the `timeout` argument was ignored). The only removal sites are 
`Response.Handle` (on reply) and the write-error branch. If the write succeeds 
and the connection drops before the server replies, `getty`'s 
`removeSession`/`close` never fail the in-flight `pendingResponses`, so the 
entry leaks in the global `sync.Map` and the `AsyncCallback` never fires — the 
caller hangs. Distinct from #3440 (write-error-path cleanup); this is the 
no-reply / connection-drop path.
   
   ## Fix
   
   After a successful `client.client.Request`, install `time.AfterFunc(timeout, 
...)` that calls `RemovePendingResponse(seq)`. If it returns non-nil (reply has 
not arrived), invoke `pr.Callback(pr.GetCallResponse())` with a timeout error. 
`RemovePendingResponse` is an atomic load-and-delete (`sync.Map`), so the timer 
and the reply path (`Response.Handle`) cannot both win the pending — 
exactly-once callback. `timeout == 0` preserves the previous wait-forever 
behavior.
   
   ## Tests
   
   Added `TestExchangeClientAsyncRequestTimeoutCallback`: a mock client whose 
`Request` succeeds and never delivers a reply (simulating connection drop); 
asserts the `AsyncCallback` fires with a timeout error and the global map does 
not leak. `remoting` package passes under `-race`.
   
   Fixes #3530


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

Reply via email to