diff --git a/.luacheckrc b/.luacheckrc index ecfcce2e72..e7fb65c82b 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -3,3 +3,8 @@ globals = { '_TEST' } exclude_files = {'./rootfs/etc/nginx/lua/test/**/*.lua'} +files["rootfs/etc/nginx/lua/lua_ingress.lua"] = { + ignore = { "122" }, + -- TODO(elvinefendi) figure out why this does not work + --read_globals = {"math.randomseed"}, +} diff --git a/build/static-check.sh b/build/static-check.sh index 1d91594015..358cb9ef89 100755 --- a/build/static-check.sh +++ b/build/static-check.sh @@ -25,4 +25,4 @@ fi hack/verify-all.sh -luacheck -q rootfs/etc/nginx/lua/ +luacheck --codes -q rootfs/etc/nginx/lua/ diff --git a/rootfs/etc/nginx/lua/lua_ingress.lua b/rootfs/etc/nginx/lua/lua_ingress.lua new file mode 100644 index 0000000000..f0d33db818 --- /dev/null +++ b/rootfs/etc/nginx/lua/lua_ingress.lua @@ -0,0 +1,26 @@ +local _M = {} + +local seeds = {} +local original_randomseed = math.randomseed +math.randomseed = function(seed) + local pid = ngx.worker.pid() + + if seeds[pid] then + ngx.log(ngx.WARN, + string.format("ignoring math.randomseed(%d) since PRNG is already seeded for worker %d", seed, pid)) + return + end + + original_randomseed(seed) + seeds[pid] = seed +end + +local function randomseed() + math.randomseed(ngx.time() + ngx.worker.pid()) +end + +function _M.init_worker() + randomseed() +end + +return _M diff --git a/rootfs/etc/nginx/lua/test/lua_ingress_test.lua b/rootfs/etc/nginx/lua/test/lua_ingress_test.lua new file mode 100644 index 0000000000..89d3150ef8 --- /dev/null +++ b/rootfs/etc/nginx/lua/test/lua_ingress_test.lua @@ -0,0 +1,9 @@ +describe("lua_ingress", function() + it("patches math.randomseed to not be called more than once per worker", function() + local s = spy.on(ngx, "log") + + math.randomseed(100) + assert.spy(s).was_called_with(ngx.WARN, + string.format("ignoring math.randomseed(%d) since PRNG is already seeded for worker %d", 100, ngx.worker.pid())) + end) +end) diff --git a/rootfs/etc/nginx/lua/test/run.lua b/rootfs/etc/nginx/lua/test/run.lua index 4d20dd2334..dcf6e800ea 100644 --- a/rootfs/etc/nginx/lua/test/run.lua +++ b/rootfs/etc/nginx/lua/test/run.lua @@ -1,4 +1,5 @@ local ffi = require("ffi") +local lua_ingress = require("lua_ingress") -- without this we get errors such as "attempt to redefine XXX" local old_cdef = ffi.cdef @@ -32,7 +33,6 @@ end ngx.log = function(...) end ngx.print = function(...) end --- TODO(elvinefendi) once this is implemented for production (should be!), share the same code -math.randomseed(ngx.time() + ngx.worker.pid()) +lua_ingress.init_worker() require "busted.runner"({ standalone = false }) diff --git a/rootfs/etc/nginx/template/nginx.tmpl b/rootfs/etc/nginx/template/nginx.tmpl index 7d3355be76..877186bcef 100644 --- a/rootfs/etc/nginx/template/nginx.tmpl +++ b/rootfs/etc/nginx/template/nginx.tmpl @@ -63,6 +63,13 @@ http { -- init modules local ok, res + ok, res = pcall(require, "lua_ingress") + if not ok then + error("require failed: " .. tostring(res)) + else + lua_ingress = res + end + ok, res = pcall(require, "configuration") if not ok then error("require failed: " .. tostring(res)) @@ -98,6 +105,7 @@ http { } init_worker_by_lua_block { + lua_ingress.init_worker() balancer.init_worker() {{ if $all.EnableMetrics }} monitor.init_worker()