btw, here is another example with true multi-threaded application using 
[threadproxy](https://github.com/jackhftang/threadproxy.nim) which is designed 
to simplify Nim inter-thread communication, but again it is not `squeeze out 
the maximum performance` type. Also, just like others have said async is more 
than enough in this scenario.
    
    
    import deques
    import threadproxy
    import http_client_pool
    
    let urls = [
      "https://google.com";,
      "https://yahoo.com";,
      "https://forum.nim-lang.org";,
      "https://somenotexisting.com";, # Name or service not known
      "https://127.0.0.1";,
      "https://192.168.0.10";, # timeout
    ]
    
    type
      LinkCheckResult = object
        url: string
        state: bool
    
    proc workerMain(proxy: ThreadProxy) {.thread.} =
      let pool = newHttpclientPool(1)
      proc process() {.async.} =
        let job = await proxy.ask("master", "job")
        if job.kind == JNull:
          # no more job
          proxy.stop()
        else:
          # process job
          let url = job.getStr()
          
          var state = false
          try:
            let res = await pool.request(url, timeout=2000)
            let _ = await res.body()
            state = true
          except:
            discard
          
          await proxy.send("master", "result", %*{
            "url": url,
            "state": state
          })
      
      # start processing channel
      asyncCheck proxy.poll()
      while proxy.isRunning:
        waitFor process()
    
    proc main() =
      # prepare jobs
      var jobs = initDeque[string]()
      for url in urls: jobs.addLast url
      
      # prepare results
      var linkCheckResults: seq[LinkCheckResult]
      
      # create and setup MainThreadProxy
      let proxy = newMainThreadProxy("master")
      
      # on worker sending back result
      proxy.onData "result":
        echo "result ", linkCheckResults.len, " ", data
        linkCheckResults.add LinkCheckResult(
          url: data["url"].getStr(),
          state: data["state"].getBool()
        )
        
        if linkCheckResults.len == urls.len:
          # all done
          proxy.stop()
      
      # on workers asking for job
      proxy.onData "job":
        # handle thread asking for job
        if jobs.len > 0:
          result = %jobs.popFirst
          echo "distributing ", result
        else:
          # return null if no more job
          result = newJNull()
      
      # create 4 worker threads
      for i in 1 .. 4:
        proxy.createThread("worker_" & $i, workerMain)
      
      # poll until proxy stop
      waitFor proxy.poll()
      
      # print results
      for x in linkCheckResults:
        if x.state:
          echo "[+] ", x.url
        else:
          echo "[ ] ", x.url
    
    when isMainModule:
      main()
    
    
    Run

Reply via email to