Async: wrong behavior of boolean operations on futures #4333

Closed
cheatfate opened this Issue Jun 14, 2016 · 7 comments

Projects

None yet

2 participants

@cheatfate
Contributor

I have modified asynchttpserver.nim to use timeouts here:
https://github.com/nim-lang/Nim/blob/devel/lib/pure/asynchttpserver.nim#L122-L125
It was like:

    await client.recvLineInto(lineFut) # TODO: Timeouts.
    if lineFut.mget == "":
      client.close()
      return

After modification:

    var rliFut = client.recvLineInto(lineFut)
    var sleFut = sleepAsync(3000)
    await rliFut or sleFut # TODO: Timeouts.
    if not rliFut.finished or lineFut.mget == "":
      client.close()
      return

And now after first client attempted to connect to asynchttpserver, it generates an error:

Traceback (most recent call last)
asynchttpserver.nim(251) asynchttpserver
asynchttpserver.nim(250) main
asyncdispatch.nim(1676)  runForever
asyncdispatch.nim(1063)  poll
asyncdispatch.nim(1183)  cb
asyncdispatch.nim(216)   complete
asyncdispatch.nim(1291)  cb
os.nim(1167)             recvLineIntoIter
asyncdispatch.nim(225)   complete
asyncdispatch.nim(353)   cb
asyncdispatch.nim(225)   complete
asyncdispatch.nim(1303)  cb
asyncdispatch.nim(245)   fail
asyncdispatch.nim(334)   :anonymous
Error: unhandled exception: Future still in progress.
  processClient's lead up to read of failed Future:
    Traceback (most recent call last)
    asynchttpserver.nim(251) asynchttpserver
    asynchttpserver.nim(250) main
    asyncdispatch.nim(1676)  runForever
    asyncdispatch.nim(1063)  poll
    asyncdispatch.nim(1183)  cb
    asyncdispatch.nim(216)   complete
    asyncdispatch.nim(1291)  cb
    os.nim(1167)             recvLineIntoIter
    asyncdispatch.nim(225)   complete
    asyncdispatch.nim(353)   cb
    asyncdispatch.nim(225)   complete
    asyncdispatch.nim(1291)  cb
    asyncdispatch.nim        processClientIter
    asyncdispatch.nim(297)   read [Exception]
@cheatfate
Contributor

And now i'm totally sure this bug is a regression, caused by callSoon().
I have disabled callSoon() by removing it from line 263.

Before:
callSoon(future.cb)

After:
future.cb()

and bug disappeared

@cheatfate
Contributor

@dom96 it looks like await macro expanded to this:

      var rliFut = client.recvLineInto(lineFut)
      var sleFut = sleepAsync(3000)
      yield rliFut or sleFut
      rliFut or sleFut.read
      if not rliFut.finished or lineFut.mget == "":
        client.close()
        complete(retFuture)
        return nil
@dom96
Member
dom96 commented Jun 14, 2016

hrm, that looks wrong.

@dom96
Member
dom96 commented Jun 14, 2016

Please try:

    var rliFut = client.recvLineInto(lineFut)
    var sleFut = sleepAsync(3000)
    var orFut = rliFut or sleFut
    await orFut # TODO: Timeouts.
    if not rliFut.finished or lineFut.mget == "":
      client.close()
      return
@cheatfate
Contributor

@dom96 your variant was expanded and works as expected.

@cheatfate
Contributor

Looks like this is new variant for {.async.} macro

@cheatfate cheatfate changed the title from asynchttpserver.nim no longer support timeouts? to Async: wrong behavior of boolean operations on futures Jun 14, 2016
@dom96 dom96 referenced this issue in dom96/notifications Jun 15, 2016
Closed

Crash when displaying a message #1

@dom96 dom96 added the async label Jun 15, 2016
@dom96
Member
dom96 commented Jun 15, 2016

I think we can fix this and #4170 at the same time.

@dom96 dom96 closed this in 500aa0c Jun 15, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment