howl.dispatch

launch(f, ...)

invokes <f> in a coroutine with the specified arguments

f = spy.new ->
  _, is_main = coroutine.running!
  assert.is_false is_main

dispatch.launch f, 1, nil, 'three'
assert.spy(f).was_called_with 1, nil, 'three'

(when <f> starts correctly)

returns true, the coroutine status, and the coroutine

status, co_status, co = dispatch.launch -> nil
assert.is_true status
assert.equals 'dead', co_status
assert.equals 'dead', coroutine.status(co)

(when <f> errors upon start)

returns false, the error message and the coroutine

status, err, co = dispatch.launch -> error 'foo'
assert.is_false status
assert.equals 'foo', err
assert.equals 'dead', coroutine.status(co)

wait()

yields until resumed using resume() on the parked handle

handle = dispatch.park 'test'
done = false

dispatch.launch ->
  dispatch.wait handle
  done = true

assert.is_false done
dispatch.resume handle
assert.is_true done

returns any parameters passed to resume()

handle = dispatch.park 'test'
local res

dispatch.launch ->
  res = { dispatch.wait handle }

dispatch.resume handle, 1, nil, 'three', nil
assert.same { 1, nil, 'three', nil }, res

raises an error when resumed with resume_with_error()

handle = dispatch.park 'test'
local err

dispatch.launch ->
  status, err = pcall dispatch.wait, handle
  assert.is_false status

dispatch.resume_with_error handle, 'blargh!'
assert.includes err, 'blargh!'

resume()

propagates any error occurring during resuming

handle = dispatch.park 'test'

dispatch.launch ->
  dispatch.wait handle
  error 'boom'

assert.raises 'boom', -> dispatch.resume handle

(when nothing is yet waiting on the parking)

it 'blocks until released by a wait', (done) ->

howl_async ->
  handle = dispatch.park 'out-of-order'
  launched, status = dispatch.launch -> dispatch.resume handle, 'resume-now!'
  assert.is_true launched
  assert.equals "suspended", status

  launched, status = dispatch.launch ->
    assert.equals 'resume-now!', dispatch.wait handle
    done!

  assert.is_true launched
  assert.equals "dead", status