Hi all.
I had some trouble the other day with an async server I was working on. I eventually boiled the problem down to an issue with defer:
import asyncdispatch, asyncnet
proc communicate(): Future[string] {.async.} =
let conn = newAsyncSocket()
await conn.connect("localhost", Port(1234))
defer:
echo "closing"
conn.close()
echo "sending"
await conn.send("foo\n")
echo "getting"
let value = await conn.recvLine()
echo "done"
return value
echo waitFor(communicate())
Set up any echo server on port 1234 (I used nc -l -p 1234 -e 'xargs -n1 echo'), run the code, and you'll observe the following output:
sending
closing
getting
closing
[enormous stack trace]
What's happening here is the defer block is getting run each time I await, contrary to the expectation that it would run once at the end of the function (or on exception).
Now, as I understand it, using async with try (as is implicitly happening with defer here) is known to not really be working correctly. It's for that reason that I thought I'd check first before actually creating an issue.
So, my question is: do we care about calling this a bug, or is this just a case of an unsupported feature?
For the record, nim -v:
Nim Compiler Version 0.18.0 [Windows: amd64]
Copyright (c) 2006-2018 by Andreas Rumpf
git hash: 5ee9e86c87d831d32441db658046fc989a197ac9
active boot switches: -d:release