It took way too long until I fully understood what you wrote. I think the key 
thing that I read, but didn't properly register in my mind was the fact that 
`waitFor`-ing on _anything_ will do async-work on _everything_.

That was the puzzle piece that I was missing, since I wanted to do some async 
work occasionally here or there, but not to the point that it might stop me 
from immediately responding to messages.

I wrote myself a small example on how I'd set it up (basically a compileable 
version of the example you wrote) and will likely end up translating into my 
actual project. It sends a batch of messages, signals the other thread to work 
through that batch and then it waitFors on the signal again, the echo's proving 
in between the batches that async work is being done even though the waitFor is 
being done on the signal.
    
    
    import chronos
    import chronos/threadsync
    import std/[os, sequtils, atomics]
    import threading/channels
    
    var chan = newChan[int](50)
    let signal = ThreadSignalPtr.new()[]
    var thread = Thread[void]()
    var keepRunning: Atomic[bool]
    keepRunning.store(true)
    
    proc senderThread() {.thread.} =
      for i in 0..5:
        for y in i*3..(i+1)*3:
          chan.send(y)
        echo signal.fireSync()
        sleep(2000)
      
      keepRunning.store(false)
      echo signal.fireSync()
    
    proc process1Message(x: int) {.async.} =
      echo "before ", x
      await sleepAsync(1.seconds)
      echo "after ", x
    
    proc main() =
      thread.createThread(senderThread)
      
      var msg: int
      while keepRunning.load():
        echo "\nNEW LOOP"
        while chan.tryRecv(msg):
          try:
            asyncSpawn msg.process1Message()
          except CatchableError as e:
            echo "Failed for message: ", msg
        
        waitFor signal.wait()
      
      joinThread(thread)
      echo "FINISHED"
    
    main()
    
    
    Run

Reply via email to