feat(client): Implements a response cancellation mechanism to improve resource management

Added support for HTTP response context cancellation, including logic for registering, triggering, and cleaning up cancellation functions.

Introduced a responseCancels mapping and corresponding synchronization lock in FrameHandler to track and control the request lifecycle.

When the data frame type is closed, actively called cancelResponse to release related resources.

Simultaneously, during the response body reading process, identified context cancellation or timeout errors and prematurely terminated the processing flow to avoid invalid operations.
This commit is contained in:
Gouryella
2025-12-06 23:58:31 +08:00
parent 133a3892af
commit bbef7efb5e
3 changed files with 142 additions and 0 deletions

View File

@@ -77,6 +77,32 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
func (h *Handler) handleAdaptiveRequest(w http.ResponseWriter, r *http.Request, transport tunnel.Transport, requestID string, subdomain string) {
const streamingThreshold int64 = 1 * 1024 * 1024
if transport != nil {
h.responses.RegisterCancelFunc(requestID, func() {
header := protocol.DataHeader{
StreamID: requestID,
RequestID: requestID,
Type: protocol.DataTypeClose,
IsLast: true,
}
payload, poolBuffer, err := protocol.EncodeDataPayloadPooled(header, nil)
if err != nil {
return
}
frame := protocol.NewFramePooled(protocol.FrameTypeData, payload, poolBuffer)
if err := transport.SendFrame(frame); err != nil {
h.logger.Debug("Failed to send cancel frame to client",
zap.String("request_id", requestID),
zap.Error(err),
)
}
})
defer h.responses.CleanupCancelFunc(requestID)
}
buffer := make([]byte, 0, streamingThreshold)
tempBuf := make([]byte, 32*1024)