I have the following loop:
while true:
var
timeout = false
readKeys = false
block:
var
keyFuture: Future[string]
timeoutFuture: Future[void]
sequence: string
keyFuture = this.terminal.key()
if keyTranslator.activeSequence.len > 0:
debugEcho "active sequence: ", keyTranslator.activeSequence, ",
timeout"
timeoutFuture = sleepAsync(300) # TODO: make constant
timeout = true
timeoutFuture.callback =
proc () =
if not keyFuture.finished:
keyFuture.complete("")
debugEcho "wait…"
yield keyFuture
debugEcho "…done"
sequence = keyFuture.read
asyncCheck keyFuture
if timeout:
timeoutFuture.clearCallbacks
debugEcho "read sequence: ", sequence.escape
readKeys = keyTranslator.keySequence(sequence)
debugEcho "end block"
debugEcho "readKeys=", readKeys
if readKeys:
for k in keyTranslator.read:
debugEcho "read key: ", k.toUTF8.escape, " (", k.int.toHex, ")"
if k == F1.Rune: # XXX for testing only
debugEcho "F1!"
this.isRunning = false
return
if this.screen.focus != -1:
this.send KeyEvent(this.time, this.screen.focus, k)
debugEcho "end loop"
Run
This gets the following error on the yield statement after once the
timeoutFuture was active and completed the keyFuture and then the keyFuture is
used without the timeout:
Error: unhandled exception: An attempt was made to complete a Future more
than once. Details:
Future ID: 510
Created in proc: asyncfile.read
Stack trace to moment of creation:
/home/j/Personal/Projects/nim/term/src/test2.nim(55)
test2
/home/j/Personal/Projects/nim/term/src/test2.nim(52)
main
/home/j/Personal/Projects/nim/term/src/term/engine.nim(211)
run
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncdispatch.nim(1576) poll
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncdispatch.nim(1340) runOnce
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncdispatch.nim(210)
processPendingCallbacks
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncmacro.nim(34)
keyboardInputNimAsyncContinue
/home/j/Personal/Projects/nim/term/src/term/engine.nim(173)
keyboardInputIter
/home/j/Personal/Projects/nim/term/src/term/term.nim(63)
key
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncfile.nim(209)
read
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncfutures.nim(110)
newFuture
Contents (string):
Stack trace to moment of secondary completion:
Traceback (most recent call last)
/home/j/Personal/Projects/nim/term/src/test2.nim(55) test2
/home/j/Personal/Projects/nim/term/src/test2.nim(52) main
/home/j/Personal/Projects/nim/term/src/term/engine.nim(211) run
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncdispatch.nim(1576) poll
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncdispatch.nim(1306) runOnce
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncdispatch.nim(1214)
processBasicCallbacks
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncfile.nim(290) cb
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncfutures.nim(211)
complete
/home/j/.choosenim/toolchains/nim-1.2.0/lib/pure/asyncfutures.nim(154)
checkFinished [FutureError]
Run
I don't understand why the async system wants to complete the keyFuture when it
was already completed. I put the keyFuture into a block that should remove the
future all together. Could this be a bug in asyncdispatch/asyncfutures?