I need a little help with extending futures with additional context for error reporting. I can't even get my current effort to compile without commenting out a couple lines :-(.
Any pointers would certainly be appreciated.
# Background:
# - Test harness to check out how to extend a httpclient future to include
# additional context information (in this case the source url which could be
# usefull in reporting failures)
import asyncdispatch, httpclient, strutils, system
type URLinfo = object
url: string
content: string
# Non-working attempt to implement the extended future
proc fetch(url: string): Future[URLinfo] {.async.} =
var fetchResult = URLinfo()
var extendedFuture = newFuture[URLinfo]
var client = newAsyncHttpClient()
fetchResult.url = url
let future = client.getContent url
# Use subordinate *simple* http future completon to trigger the *extended* future
future.addCallback(
proc(future: Future[string]) =
fetchResult.content = future.read
echo "content: ", fetchResult.content.len
# complete(extendedFuture, fetchResult) # doesn't compile
)
discard await future
# result = extendedFuture # doesn't compile
echo "fetch finished"
proc getURLs(urls: seq[string]) : Future[seq[URLinfo]] {.async.} =
var futures: seq[Future[URLinfo]]
for url in urls:
var future = fetch url
futures.add future
result = await all futures
echo "getURLs finished"
proc main() {.async} =
const sites = @[
"https://google.com",
"https://amazon.com"
]
discard await getURLs sites
waitFor main()
echo "main finished"
This should work. Extending Future are more straightforward
# Background:
# - Test harness to check out how to extend a httpclient future to include
# additional context information (in this case the source url which could be
# usefull in reporting failures)
import std/[asyncdispatch, httpclient, strutils]
type URLinfo = object
url: string
content: string
# Non-working attempt to implement the extended future
proc fetch(url: string): Future[URLinfo] {.async.} =
let
client = newAsyncHttpClient()
future = await client.getContent url
result = URLInfo(url: url, content: future)
echo "fetch finished for url: ", url
proc getURLs(urls: seq[string]) : Future[seq[URLinfo]] {.async.} =
var futures: seq[Future[URLinfo]]
for url in urls:
var future = fetch url
futures.add future
result = await all futures
echo "getURLs finished"
proc main() {.async} =
const sites = @[
"https://google.com",
"https://youtube.com",
"https://facebook.com",
"https://twitter.com",
"https://nim-lang.org",
"https://reddit.com",
"https://amazon.com"
]
discard await getURLs sites
waitFor main()
echo "main finished"
From this code it does:
# Background:
# - Test harness to check out how to extend a httpclient future to include
# additional context information (in this case the source url which could be
# usefull in reporting failures)
import std/[asyncdispatch, httpclient, times, strformat, strutils]
type URLinfo = object
url: string
content: string
# Non-working attempt to implement the extended future
proc fetch(url: string): Future[URLinfo] {.async.} =
let
startTime = now()
client = newAsyncHttpClient()
future = await client.getContent url
result = URLInfo(url: url, content: future)
echo &"fetch finished for url: {url}\n\t from {startTime}\n\tuntil {now()}"
proc getURLs(urls: seq[string]) : Future[seq[URLinfo]] {.async.} =
var futures: seq[Future[URLinfo]]
for url in urls:
var future = fetch url
futures.add future
result = await all futures
echo "getURLs finished"
proc main() =
const sites = @[
"https://google.com",
"https://youtube.com",
"https://facebook.com",
"https://twitter.com",
"https://nim-lang.org",
"https://reddit.com",
"https://amazon.com"
]
discard waitFor getURLs sites
main()
echo "main finished"