Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot return functions in async methods #2

Closed
svermeulen opened this issue Jun 27, 2020 · 4 comments
Closed

Cannot return functions in async methods #2

svermeulen opened this issue Jun 27, 2020 · 4 comments

Comments

@svermeulen
Copy link
Contributor

svermeulen commented Jun 27, 2020

Using the implementation here, you cannot create async functions that return functions, since the returned functions will always be interpreted as a 'thunk'. I attempted to modify the pong method to allow this. In case it's useful to others, I wanted to share what I'm using instead:

local pong = function (func, callback)
  assert(type(func) == "function", "Expected type func but found " .. type(func))
  local thread = co.create(func)
  local step = nil
  step = function (...)
    local go, ret = co.resume(thread, ...)
    assert(go)
    if co.status(thread) == "dead" then
      if callback then
        callback(ret)
      end
    else
      assert(type(ret) == "function")
      ret(step)
    end
  end
  step()
end

This allows function return values because it always calls the callback value when the coroutine is dead. Also, I think we can assume that the go value is always true now that we are checking the co.status immediately after the call to resume

@ms-jpq
Copy link
Owner

ms-jpq commented Jun 27, 2020

Thank you!

Really good catch, but by the looks of it doing this will swollow errors from coroutines.

When I have more time Ill try to figure out how to make it all work nicely :D

Sorry Ill leave this issue hanging for a bit, brain is foggy right now

@ms-jpq ms-jpq pinned this issue Jun 27, 2020
@ms-jpq
Copy link
Owner

ms-jpq commented Jun 27, 2020

Also you are from halifax!

ohhhhhhhhh canada, our home and native land.

Go Canada!

@svermeulen
Copy link
Contributor Author

Haha, yes, I see you are a fellow canadian as well :)

Yes, you are correct. I realize now that go will be false when exceptions occur. I've now modified it to this instead:

local pong = function (func, callback)
  assert(type(func) == "function", "Expected type func but found " .. type(func))
  local thread = co.create(func)
  local step = nil
  step = function (...)
    local go, ret = co.resume(thread, ...)
    assert(go, "Async function failed! Details: " .. ret)
    if co.status(thread) == "dead" then
      if callback then
        callback(ret)
      end
    else
      assert(type(ret) == "function")
      ret(step)
    end
  end
  step()
end

@ms-jpq
Copy link
Owner

ms-jpq commented Jun 28, 2020

i have update the code, thank you.

also added you to the read me #thank section 👍

local async_tasks_2 = function (val)
  return a.sync(function ()
    -- await all
    local w, z = a.wait_all{e2(val, val + 1), e2(val + 2, val + 3)}
    print(unpack(w))
    print(unpack(z))
    return function ()
      return 4
    end
  end)
end

the example code works with func returns

@ms-jpq ms-jpq closed this as completed Jun 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants