Hi ereryone!
Since the async httpclient proc do not have a timeout option, I just check if it is failed in the "async way", which is like posted below:
(It's not the complete code, but the core code of my program)
The code is written to download some imgs using urls in a txt file. And it was Inspired by this article:
It can catch some fails in most of time. But sometimes on the other hand ,the program will run and be dead.
(the console just Stuck in some step and wont go any further)
type
UrlCheckResult* = ref object
url*: string
saveName*: string
data*: string # data of the img
error*: string
proc checkUrlAsync*(url: string, saveName: string,
proxy: Proxy): Future[UrlCheckResult] {.async.} =
var client = newAsyncHttpClient(userAgent=uA, proxy = proxy, maxRedirects = 1)
let future = client.get(url)
yield future
if future.failed():
return UrlCheckResult(url: url, error: "failed-get")
else:
let body = await future.read().body()
return UrlCheckResult(url: url, saveName: saveName,
data: body, error: "")
for url in urlLines[asyncBeg .. asyncEnd]:
if url.len > 0:
var saveName: string
var beg: int = rfind(url, "/")
var filename = url[beg+1 .. url.len()-1].replaceIlligelNameString()
saveName = saveRoot.joinPath(filename)
if genConfig["ignoreExist"].getBool():
if existsFile(saveName):
inc existCount
eraseLine()
write(stdout, fmt"* ExistIgnore:[{filename}][{existCount}]")
sleep(10)
continue
futures.add(checkUrlAsync(url, saveName, proxy = myProxy))
let done = waitFor all(futures)
futures = @[]
As I am not a professional programmer , and neither familiar with the http protocol. I can not figure out what happens to my program. I wish someone can help me to figure it out. :-)
Code looks good to me.
you can drive your async loop with:
runForever()
which boils down to:
while true:
poll()
or you can
waitFor() # drives an async loop and also returns value.
Then inside an async proc:
await # blocks and returns a value
or
asyncCheck # does not block but does not return a value.
So in your case,
you could loop over futures and call await on your future.
Or you could loop over futures and call
asyncCheck
then in another loop, check if all futures are finished.