shuaijinchao edited a comment on issue #4077:
URL: https://github.com/apache/apisix/issues/4077#issuecomment-966193860


   > > @Ben0625 Could you try the `2.5` version? And test it whether it can be 
reproduced in `2.5`?
   > 
   > We get the same problems on the apisix 2.8
   > 
   > I found a bug in 
[api7/lua-resty-healthcheck@`master`/lib/resty/healthcheck.lua](https://github.com/api7/lua-resty-healthcheck/blob/master/lib/resty/healthcheck.lua?rgh-link-date=2021-11-10T08%3A27%3A57Z)
 The content of var `defaults` will be modified when not assigned the passive 
or active config item
   > 
   > Reproduce the bug: nginx.conf
   > 
   > ```lua
   > daemon off;
   > worker_processes  1;
   > error_log stderr;
   > events {
   >     worker_connections 1024;
   > }
   > http {
   >     access_log off;
   >     server {
   >         listen 19000;
   >         location / {
   >             default_type text/html;
   >             content_by_lua '
   >                 ngx.say("<p>Hello, World!</p>")
   >             ';
   >             log_by_lua '
   >                 local check = require("check")
   >             ';
   >         }
   >     }
   > }
   > ```
   > 
   > check.lua
   > 
   > ```lua
   > local cjson = require("cjson.safe")
   > 
   > -- copy from: 
https://github.com/api7/lua-resty-healthcheck/blob/master/lib/resty/healthcheck.lua#L1162
   > 
--============================================================================
   > -- Create health-checkers
   > 
--============================================================================
   > 
   > 
   > local NO_DEFAULT = {}
   > local MAXNUM = 2^31 - 1
   > 
   > 
   > local function fail(ctx, k, msg)
   >   ctx[#ctx + 1] = k
   >   error(table.concat(ctx, ".") .. ": " .. msg, #ctx + 1)
   > end
   > 
   > 
   > local function fill_in_settings(opts, defaults, ctx)
   >   ctx = ctx or {}
   >   local obj = {}
   >   for k, default in pairs(defaults) do
   >     local v = opts[k]
   > 
   >     -- basic type-check of configuration
   >     if default ~= NO_DEFAULT
   >     and v ~= nil
   >     and type(v) ~= type(default) then
   >       fail(ctx, k, "invalid value")
   >     end
   > 
   >     if v ~= nil then
   >       if type(v) == "table" then
   >         if default[1] then -- do not recurse on arrays
   >           obj[k] = v
   >         else
   >           ctx[#ctx + 1] = k
   >           obj[k] = fill_in_settings(v, default, ctx)
   >           ctx[#ctx + 1] = nil
   >         end
   >       else
   >         if type(v) == "number" and (v < 0 or v > MAXNUM) then
   >           fail(ctx, k, "must be between 0 and " .. MAXNUM)
   >         end
   >         obj[k] = v
   >       end
   >     elseif default ~= NO_DEFAULT then
   >       obj[k] = default
   >     end
   > 
   >   end
   >   return obj
   > end
   > 
   > 
   > local defaults = {
   >   name = NO_DEFAULT,
   >   shm_name = NO_DEFAULT,
   >   type = NO_DEFAULT,
   >   status_ver = 0,
   >   checks = {
   >     active = {
   >       type = "http",
   >       timeout = 1,
   >       concurrency = 10,
   >       http_path = "/",
   >       https_verify_certificate = true,
   >       healthy = {
   >         interval = 0, -- 0 = disabled by default
   >         http_statuses = { 200, 302 },
   >         successes = 2,
   >       },
   >       unhealthy = {
   >         interval = 0, -- 0 = disabled by default
   >         http_statuses = { 429, 404,
   >                           500, 501, 502, 503, 504, 505 },
   >         tcp_failures = 2,
   >         timeouts = 3,
   >         http_failures = 5,
   >       },
   >       req_headers = {""},
   >     },
   >     passive = {
   >       type = "http",
   >       healthy = {
   >         http_statuses = { 200, 201, 202, 203, 204, 205, 206, 207, 208, 226,
   >                           300, 301, 302, 303, 304, 305, 306, 307, 308 },
   >         successes = 5,
   >       },
   >       unhealthy = {
   >         http_statuses = { 429, 500, 503 },
   >         tcp_failures = 2,
   >         timeouts = 7,
   >         http_failures = 5,
   >       },
   >     },
   >   },
   > }
   > 
   > 
   > local function to_set(tbl, key)
   >   local set = {}
   >   for _, item in ipairs(tbl[key]) do
   >     set[item] = true
   >   end
   >   tbl[key] = set
   > end
   > 
   > 
   >   -- In the below is my code
   > local option_no_passive  =  cjson.decode([[
   >     {
   >         "checks":
   >         {
   >             
"active":{"unhealthy":{"tcp_Failures":3,"http_statuses":[500,501,502,503,504,505],"timeouts":3,"interval":100,"tcp_failures":2,"http_failures":3},"concurrency":10,"http_path":"\/healthz","https_verify_certificate":true,"port":9080,"type":"http","healthy":{"interval":5,"successes":1,"http_statuses":[200,201,202,203,204,205,206,207,208,226,300,301,302,303,304,305,306,307,308,400,401,403,404,405,415,429]},"host":"healthcheck","timeout":5}
   >         },
   >         
"name":"upstream#\/internal-apisix\/upstreams\/380542682478412600","shm_name":"upstream-healthcheck"
   >     }]])
   > -- The default can be encoded to json
   > ngx.log(ngx.ERR, "===defaults: ", cjson.encode(defaults))
   > 
   > -- The default `passive` config will be filled into 
`filled_option_no_passive` by the method `fill_in_settings`
   > local filled_option_no_passive = fill_in_settings(option_no_passive 
,defaults)
   > ngx.log(ngx.ERR, "===filled_option_no_passive: ", 
cjson.encode(filled_option_no_passive))
   > 
   > -- copy from: 
https://github.com/api7/lua-resty-healthcheck/blob/master/lib/resty/healthcheck.lua#L1364
   > to_set(filled_option_no_passive.checks.active.unhealthy, "http_statuses")
   > to_set(filled_option_no_passive.checks.active.healthy, "http_statuses")
   > to_set(filled_option_no_passive.checks.passive.unhealthy, "http_statuses")
   > to_set(filled_option_no_passive.checks.passive.healthy, "http_statuses")
   > 
   > -- print: nil Cannot serialise table: excessively sparse array while 
logging request
   > -- The defaults has been modified by `to_set`
   > ngx.log(ngx.ERR, "===defaults: ", cjson.encode(defaults))
   > ```
   
   ---
   
   @chzhuo your question does not seem to be related to @Ben0625's question. 
Regarding the issue of "Unable to serialize table: too sparse array", please 
refer to the lua-cjson document: [kyne.com.au/~mark/software/lua-cjson 
-manual.html#encode_sparse_array](https://kyne.com.au/~mark/software/lua-cjson-manual.html#encode_sparse_array)
   
   
![image](https://user-images.githubusercontent.com/8529452/141283994-cb7e99b6-dbae-4039-857f-2b984293e66f.png)
   


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