Skip to content

Commit

Permalink
fix(timeouts) failing errors handlers in Lua 5.1
Browse files Browse the repository at this point in the history
see underlying bug: keplerproject/coxpcall#18
  • Loading branch information
Tieske committed Oct 3, 2022
1 parent 154ec40 commit 2f56080
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 3 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ test: certs
$(LUA) $(DELIM) $(PKGPATH) tests/starve.lua
$(LUA) $(DELIM) $(PKGPATH) tests/tcptimeout.lua
$(LUA) $(DELIM) $(PKGPATH) tests/timer.lua
$(LUA) $(DELIM) $(PKGPATH) tests/timeout_errors.lua
$(LUA) $(DELIM) $(PKGPATH) tests/tls-sni.lua
$(LUA) $(DELIM) $(PKGPATH) tests/udptimeout.lua
$(LUA) $(DELIM)
Expand Down
7 changes: 7 additions & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ <h2><a name="dependencies"></a>Dependencies</h2>
<h2><a name="history"></a>History</h2>

<dl class="history">
<dt><strong>Copas 4.3.x</strong> [unreleased]</dt>
<dd><ul>
<li>Fix: error handler for timeouts. Underlying <a href="https://github.com/keplerproject/coxpcall/issues/18">
bug is in coxpcall</a>, and hence this only applies to PuC Lua 5.1.
</li>
</ul></dd>

<dt><strong>Copas 4.3.1</strong> [21/Sep/2022]</dt>
<dd><ul>
<li>Fix: with Lua 5.1 the timeouts would resume the wrapped (by coxpcall)
Expand Down
7 changes: 5 additions & 2 deletions src/copas.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1236,13 +1236,16 @@ end

do
local timeout_register = setmetatable({}, { __mode = "k" })
local time_out_thread
local timerwheel = require("timerwheel").new({
precision = TIMEOUT_PRECISION, -- timeout precision 100ms
ringsize = math.floor(60/TIMEOUT_PRECISION), -- ring size 1 minute
err_handler = function(...) return _deferror(...) end,
err_handler = function(err)
return _deferror(err, time_out_thread)
end,
})

copas.addnamedthread("copas_core_timer", function()
time_out_thread = copas.addnamedthread("copas_core_timer", function()
while true do
copas.sleep(TIMEOUT_PRECISION)
timerwheel:step()
Expand Down
2 changes: 1 addition & 1 deletion tests/errhandlers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ if _VERSION ~= "Lua 5.1" then

print = old_print --luacheck: ignore

assert(msg:find("errhandlers%.lua:%d-: hi there! %(coroutine: nil, socket: nil%)"), "got:\n"..msg)
assert(msg:find("errhandlers%.lua:%d-: hi there! %(coroutine: copas_core_timer, socket: nil%)"), "got:\n"..msg)
assert(msg:find("stack traceback:.+errhandlers%.lua"), "got:\n"..msg)
end
end
Expand Down
50 changes: 50 additions & 0 deletions tests/timeout_errors.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
-- Tests Copas timeout mnechanism, when a timeout handler errors out
--
-- Run the test file, it should exit successfully without hanging.

-- make sure we are pointing to the local copas first
package.path = string.format("../src/?.lua;%s", package.path)
local copas = require("copas")


local tests = {}


function tests.error_on_timeout()
local err_received

copas.addthread(function()
copas.setErrorHandler(function(err, coro, skt)
err_received = err
end, true)
print "setting timeout in 0.1 seconds"
copas.timeout(0.1, function()
print "throwing an error now..."
error("oops...")
end)
print "going to sleep for 1 second"
copas.sleep(1)

if not (err_received or ""):find("oops...", 1, true) then
print("expected to find the error string 'oops...', but got: " .. tostring(err_received))
os.exit(1)
end
end)

copas.loop()
end





-- test "framework"
for name, test in pairs(tests) do
print("testing: "..tostring(name))
local status, err = pcall(test)
if not status then
error(err)
end
end

print("[✓] all tests completed successuly")

0 comments on commit 2f56080

Please sign in to comment.