Skip to content

Commit

Permalink
fix(compat) OpenResty implementation of coroutine.wrap
Browse files Browse the repository at this point in the history
  • Loading branch information
Tieske committed Sep 22, 2020
1 parent d95c4d2 commit c6178be
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 17 deletions.
4 changes: 0 additions & 4 deletions .luacheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ max_line_length = false

globals = {
"ngx",
"coroutine._wrap",
"coroutine._yield",
"coroutine._create",
"coroutine._resume",
}

not_globals = {
Expand Down
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
# Changelog

## 1.x.x (upcoming)
## 1.9.0 (2020-09-22)

### New features

- `compat.wrap` a `coroutine.wrap` implementation that works like plain Lua
on OpenResty. (#342)

## Fixes

- In `pl.class`, `_init` can now be inherited from grandparent (or older ancestor) classes. (#289)
- In `pl.class`, `_init` can now be inherited from grandparent (or older ancestor) classes. [#289](https://github.com/lunarmodules/Penlight/pull/289)
- Using `compat.wrap` it now fixes `dir.dirtree`, `pl.lexer` on OpenResty. [#342](https://github.com/lunarmodules/Penlight/pull/342)

## 1.8.0 (2020-08-05)

Expand Down
50 changes: 50 additions & 0 deletions lua/pl/compat.lua
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,56 @@ else
end
end

--- OpenResty compatibility (broken coroutines)
-- @section openresty

--- Wraps a function into a coroutine.
-- This compatibility function is to restore `coroutine.wrap()` compatibility on
-- OpenResty. On OpenResty, when a coroutine throws an error, the wrapper return
-- `nil+err` instead of passing the hard error.
-- This function will have traditional Lua behaviour on all implementations.
-- @function compat.wrap
-- @param func function to wrap into a coroutine
-- @return a coroutine (thread type)
do
-- coroutine.wrap compat, for bad openresty implementation
-- check by validating behaviour
local count do
local i = 0
function count()
while i < 10 do
i = i + 1
assert(i < 2) -- 1st pass succeeds, 2nd fails
coroutine.yield(i)
end
end
end
local test_coro = coroutine.wrap(count)
pcall(test_coro) -- succeeds, 1st pass
local ok = pcall(test_coro) -- 2nd pass, should fail
if not ok then
-- it failed as expected, this is the right thing
compat.wrap = coroutine.wrap
else
-- the pcall returned success because the bad openresty implementation returns
-- nil+err instead of throwing a hard error, so we need to fix that.
-- Reimplemented coroutine.wrap to be original Lua compliant
compat.wrap = function(func)
local co = coroutine.create(func)
return function(...)
local results = table.pack(coroutine.resume(co, ...))
if results[1] then
-- success
return table.unpack(results, 2, results.n)
else
-- it failed
return error("coroutine failed with: " .. results[2])
end
end
end
end
end

--- Global exported functions (for Lua 5.1 & LuaJIT)
-- @section lua52

Expand Down
6 changes: 3 additions & 3 deletions lua/pl/dir.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ local remove = os.remove
local append = table.insert
local assert_arg,assert_string,raise = utils.assert_arg,utils.assert_string,utils.raise

-- check on OpenResty coroutine versions, and use originals if possible
local wrap = coroutine._wrap or coroutine.wrap
local yield = coroutine._yield or coroutine.yield
-- check for OpenResty coroutine versions
local wrap = require("pl.compat").wrap
local yield = coroutine.yield


local dir = {}
Expand Down
6 changes: 3 additions & 3 deletions lua/pl/lexer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ local strfind = string.find
local strsub = string.sub
local append = table.insert

-- check on OpenResty coroutine versions, and use originals if possible
local wrap = coroutine._wrap or coroutine.wrap
local yield = coroutine._yield or coroutine.yield
-- check for OpenResty coroutine versions
local wrap = require("pl.compat").wrap
local yield = coroutine.yield


local function assert_arg(idx,val,tp)
Expand Down
8 changes: 3 additions & 5 deletions lua/pl/permute.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ local utils = require 'pl.utils'
local copy = tablex.deepcopy
local append = table.insert
local assert_arg = utils.assert_arg

-- check on OpenResty coroutine versions, and use originals if possible
local co_create = coroutine._create or coroutine.create
local co_yield = coroutine._yield or coroutine.yield
local co_resume = coroutine._resume or coroutine.resume
local co_create = coroutine.create
local co_yield = coroutine.yield
local co_resume = coroutine.resume


local permute = {}
Expand Down

0 comments on commit c6178be

Please sign in to comment.