moonming opened a new pull request, #14192:
URL: https://github.com/apache/apisix/pull/14192

   ### Description
   
   `execute_func` in `apisix/utils/batch-processor.lua` calls a logger's batch 
callback directly. When the callback raises an error instead of returning 
`false, err`, the timer is aborted (`lua entry thread aborted: runtime error: 
...`), the batch skips the retry policy, and its entries are never added to 
`processed_entries`.
   
   Since #13826 the backlog limit is on by default (`max_pending_entries`, 
8192), and the backlog is computed as `total_pushed_entries - processed 
entries`. Every entry of a batch whose callback raised therefore stays 
"pending" for the rest of the worker's life. Once 8192 of them have 
accumulated, the worker discards every new entry of that logger, and neither 
fixing the log server nor changing the route brings it back; only a reload or 
restart does. Before 3.18 the same leak happened only when 
`max_pending_entries` was configured.
   
   Reproduced with the `apache/apisix:3.19.0-debian` image, whose batch 
processor files are identical to master: `splunk-hec-logging` with its default 
batch settings, pointed at an endpoint that answers `403 
{"message":"Forbidden"}` (the nil concatenation in #14011), with 
`worker_processes: 1`.
   
   | | before | with this PR |
   |---|---|---|
   | 9,499 requests while the endpoint answers 403 | 9 batches abort with 
`attempt to concatenate field 'text'`; the log then shows 
`total_pushed_entries: 8192 total_processed_entries: 0` and entries are 
discarded | 10 batches fail through the normal path (`Batch 
Processor[splunk-hec-logging] failed to process entries: ...`); nothing is 
discarded |
   | endpoint changed to one that answers 200, then 300 more requests | no 
batch reaches it; entries are still discarded | the batch is delivered |
   
   This PR:
   
   1. Calls the callback through `pcall`. A raised error is handled like a 
`false` return, so the batch is retried according to `max_retry_count` and 
counted as processed when it is dropped. The error is logged in the existing 
`failed to process entries: <err>` line.
   2. Counts a batch as processed when its timer cannot be created (`failed to 
create process timer: ...`, e.g. `too many pending timers`). That was the other 
path that dropped a batch without counting it, with the same effect on the 
backlog.
   3. Adds one sentence to the batch processor docs (en and zh) saying that a 
callback that raises is treated as a failed batch.
   
   Per-plugin fixes such as #14012 are still useful for clearer error messages, 
but with this change a bug in one logger's callback can no longer turn that 
logger off for the rest of the worker's life.
   
   #### Tests
   
   - `t/utils/batch-processor.t` TEST 14: a callback that raises is called 
again on retry and is then dropped with `exceeded the max_retry_count`, 
`processed_entries` becomes 1, and no `lua entry thread aborted` is logged.
   - `t/utils/batch-processor.t` TEST 15: when `ngx.timer.at` fails, the 
dropped batch is counted in `processed_entries`.
   - `t/utils/batch-processor-manager.t` TEST 8: with `max_pending_entries = 
2`, two entries whose callback raised do not block the next two entries.
   
   All three tests fail on master and pass with this change. 
`t/utils/batch-processor.t` and `t/utils/batch-processor-manager.t` (90 tests) 
pass locally, and a set of logger plugin test files gives the same results with 
and without the change (details below). `lj-releng` and `reindex` pass; 
`luacheck` was not run locally and relies on CI.
   
   #### Notes for reviewers
   
   - A raising callback is now retried like a failing one. For a deterministic 
error the retries are wasted work, but they are bounded by `max_retry_count` 
(default 0), which is the same as for a callback that returns `false` for a 
deterministic reason.
   - The uncaught error used to come with a stack trace; it is now logged as 
the error message only, which still carries the file and line of the throw.
   
   #### Which issue(s) this PR fixes:
   
   Related to #14011, #14012, #14003, #14004
   
   ### Checklist
   
   - [x] I have explained the need for this PR and the problem it solves
   - [x] I have explained the changes or the new features added to this PR
   - [x] I have added tests corresponding to this change
   - [x] I have updated the documentation to reflect this change (one sentence 
in the batch processor docs, en and zh)
   - [x] I have verified that this change is backward compatible (If not, 
please discuss on the [APISIX mailing 
list](https://github.com/apache/apisix/tree/master#community) first)
   


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