Copilot commented on code in PR #13254:
URL: https://github.com/apache/apisix/pull/13254#discussion_r3104758079


##########
apisix/plugin.lua:
##########
@@ -1397,13 +1397,22 @@ function _M.run_global_rules(api_ctx, global_rules, 
conf_version, phase_name)
     end
 end
 
-function _M.lua_response_filter(api_ctx, headers, body)
+-- @param wait boolean When true, use synchronous flush (ngx.flush(true)) and 
return
+--   (ok, err) so callers can detect client disconnection. Defaults to false 
for
+--   backward compatibility (async flush, no return value).
+function _M.lua_response_filter(api_ctx, headers, body, wait)
     local plugins = api_ctx.plugins
     if not plugins or #plugins == 0 then
         -- if there is no any plugin, just print the original body to 
downstream
-        ngx_print(body)
-        ngx_flush()
-        return
+        local ok, err = ngx_print(body)
+        if not ok then
+            return false, err
+        end
+        ok, err = ngx_flush(wait)
+        if not ok then

Review Comment:
   `wait` is documented as defaulting to `false`, but when omitted it is 
actually `nil` and gets passed through to `ngx_flush(wait)`. Consider 
normalizing `wait` to a strict boolean and/or only passing an argument when 
`wait == true` (otherwise call `ngx_flush()` with no args, as before) to keep 
intent and backward-compatibility clearer.



##########
apisix/plugin.lua:
##########
@@ -1397,13 +1397,22 @@ function _M.run_global_rules(api_ctx, global_rules, 
conf_version, phase_name)
     end
 end
 
-function _M.lua_response_filter(api_ctx, headers, body)
+-- @param wait boolean When true, use synchronous flush (ngx.flush(true)) and 
return
+--   (ok, err) so callers can detect client disconnection. Defaults to false 
for
+--   backward compatibility (async flush, no return value).

Review Comment:
   The docstring says the default path uses async flush with “no return value”, 
but this function now always returns a boolean (and possibly an error) 
regardless of `wait`. Please update the comment to match the actual return 
behavior to avoid misleading callers.



##########
apisix/plugins/ai-providers/base.lua:
##########
@@ -352,14 +352,36 @@ function _M.parse_streaming_response(self, ctx, res, 
target_proto, converter)
             ::CONTINUE::
         end
 
-        -- Output: converter events or passthrough raw chunk
+        -- Output: converter events or passthrough raw chunk.
+        -- Pass wait=true for synchronous flush so we can detect client 
disconnection.
         if converter then
             for _, c in ipairs(converted_chunks) do
-                plugin.lua_response_filter(ctx, res.headers, c)
+                local ok, flush_err = plugin.lua_response_filter(ctx, 
res.headers, c, true)
                 output_sent = true
+                if not ok then
+                    core.log.info("client disconnected during AI streaming, ",
+                                  "aborting upstream read: ", flush_err)
+                    if res._httpc then
+                        res._httpc:close()
+                        res._httpc = nil
+                    end
+                    ctx.var.llm_request_done = true
+                    return
+                end
             end
         else
-            plugin.lua_response_filter(ctx, res.headers, chunk)
+            local ok, flush_err = plugin.lua_response_filter(ctx, res.headers, 
chunk, true)
+            output_sent = true
+            if not ok then
+                core.log.info("client disconnected during AI streaming, ",
+                              "aborting upstream read: ", flush_err)
+                if res._httpc then
+                    res._httpc:close()
+                    res._httpc = nil
+                end
+                ctx.var.llm_request_done = true
+                return
+            end

Review Comment:
   The client-disconnect handling logic (log + close `res._httpc` + set 
`llm_request_done` + return) is duplicated in both the converter and 
passthrough branches. Consider extracting it into a small local helper to 
reduce duplication and keep future changes consistent.



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