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?

Reply via email to