This is an automated email from the ASF dual-hosted git repository.

nic-6443 pushed a commit to branch fix/ai-proxy-client-disconnect
in repository https://gitbox.apache.org/repos/asf/apisix.git


The following commit(s) were added to refs/heads/fix/ai-proxy-client-disconnect 
by this push:
     new 4de172aeb refactor: address review comments on lua_response_filter and 
disconnect handler
4de172aeb is described below

commit 4de172aeb7b8a3a7980b989d8d41bfb2df5461a0
Author: Nic <[email protected]>
AuthorDate: Sat Apr 18 15:07:12 2026 +0800

    refactor: address review comments on lua_response_filter and disconnect 
handler
    
    - update docstring to accurately reflect that lua_response_filter always
      returns (ok, err) regardless of wait parameter
    - avoid passing nil to ngx_flush: explicitly call ngx_flush(true) when
      wait==true, ngx_flush() otherwise
    - extract abort_on_disconnect local helper in parse_streaming_response
      to deduplicate the log+close+mark-done pattern
    
    Co-authored-by: Copilot <[email protected]>
---
 apisix/plugin.lua                    | 19 ++++++++++++++-----
 apisix/plugins/ai-providers/base.lua | 26 ++++++++++++--------------
 2 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/apisix/plugin.lua b/apisix/plugin.lua
index 942efebe6..a09dc627a 100644
--- a/apisix/plugin.lua
+++ b/apisix/plugin.lua
@@ -1397,9 +1397,10 @@ function _M.run_global_rules(api_ctx, global_rules, 
conf_version, phase_name)
     end
 end
 
--- @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).
+-- @param wait boolean When true, use synchronous flush (ngx.flush(true)) so 
callers
+--   can detect client disconnection. Defaults to false (async flush).
+-- @return boolean, string|nil Always returns (ok, err). On success returns 
true.
+--   On flush failure or print failure returns false, err.
 function _M.lua_response_filter(api_ctx, headers, body, wait)
     local plugins = api_ctx.plugins
     if not plugins or #plugins == 0 then
@@ -1408,7 +1409,11 @@ function _M.lua_response_filter(api_ctx, headers, body, 
wait)
         if not ok then
             return false, err
         end
-        ok, err = ngx_flush(wait)
+        if wait then
+            ok, err = ngx_flush(true)
+        else
+            ok, err = ngx_flush()
+        end
         if not ok then
             return false, err
         end
@@ -1443,7 +1448,11 @@ function _M.lua_response_filter(api_ctx, headers, body, 
wait)
     if not ok then
         return false, err
     end
-    ok, err = ngx_flush(wait)
+    if wait then
+        ok, err = ngx_flush(true)
+    else
+        ok, err = ngx_flush()
+    end
     if not ok then
         return false, err
     end
diff --git a/apisix/plugins/ai-providers/base.lua 
b/apisix/plugins/ai-providers/base.lua
index 8227922d6..e8cfc77a3 100644
--- a/apisix/plugins/ai-providers/base.lua
+++ b/apisix/plugins/ai-providers/base.lua
@@ -272,6 +272,16 @@ function _M.parse_streaming_response(self, ctx, res, 
target_proto, converter)
     -- uncommitted and causing nginx to fall through to the balancer phase.
     local output_sent = false
 
+    local function abort_on_disconnect(flush_err)
+        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
+    end
+
     while true do
         local chunk, err = body_reader()
         ctx.var.apisix_upstream_response_time = math.floor((ngx_now() -
@@ -359,13 +369,7 @@ function _M.parse_streaming_response(self, ctx, res, 
target_proto, converter)
                 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
+                    abort_on_disconnect(flush_err)
                     return
                 end
             end
@@ -373,13 +377,7 @@ function _M.parse_streaming_response(self, ctx, res, 
target_proto, converter)
             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
+                abort_on_disconnect(flush_err)
                 return
             end
         end

Reply via email to