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