That seems to work!
    
    
    # - How can I get access to the completion time (info.finish) when the 
request
    #   has been fullfilled?
    # - My guess is that in the callback *info* is being *passed by value* so 
the timestamp
    #   (info.finish) isn't being updated ( and is returned as zero :-( )
    
    import std/[algorithm, asyncdispatch, httpclient, strutils, times]
    
    var startTime: Time
    
    type URLinfo = ref object
      start: Time
      finish: Time
      url: string
      content: string
    
    proc duration(info: URLinfo): Duration =
      info.finish - info.start
    
    proc startOffset(info: URLinfo) : Duration = # relative timestamp
      info.start - startTime
    
    proc `$`(info: URLinfo): string =
      "start " & align($(info.startOffset.inMilliseconds), 4) & " mSec  " &
      info.url & " yielded " & $(info.content.len) &
      " bytes in " & $(info.duration.inMicroseconds) & " uSec"
    
    proc fetch(url: string): Future[URLinfo] {.async.} =
      let
        startTime = getTime()
        client = newAsyncHttpClient()
      result = URLInfo(start: startTime, url: url)
      result.content = await client.getContent url
    
    proc getURLs(urls: seq[string]) : Future[seq[URLinfo]] {.async.} =
      var futures: seq[Future[URLinfo]]
      
      startTime = getTime()
      
      echo "\nCorrect durations are displayed:"
      for url in urls:
        var future = fetch url
        future.addCallback(
          proc(future: Future[URLinfo]) =
            var info = future.read
            info.finish = getTime() # Doesn't update original URLinfo :-(
            echo $info
        )
        futures.add future
      
      result = await all futures
      
      echo "\nWrong durations are displayed:"
      for entry in result.sortedByIt(it.startOffset): echo entry
    
    proc main() {.async} =
      var sites = @[
        "https://amazon.com";,
        "https://facebook.com";,
        "https://google.com";,
        "https://nim-lang.org";,
        "https://reddit.com";,
        "https://twitter.com";,
        "https://youtube.com";,
      ]
      echo "Main Finshed: ", (await getURLs sites).len, " sites"
    
    waitFor main()
    
    
    Run

Reply via email to