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?