Description
I have a question regarding the asynchronous handling of unfulfilled requests in the fetchers_concurrent.go file. Specifically, I would like clarification on the following code snippet and accompanying comment:
// Fetch the chunk and make sure any errors return the hashes to the queue
req, err := queue.request(peer, request, responses)
if err != nil {
// Sending the request failed, which generally means the peer
// was disconnected in between assignment and network send.
// Although all peer removal operations return allocated tasks
// to the queue, that is async, and we can do better here by
// immediately pushing the unfulfilled requests.
queue.unreserve(peer.id) // TODO(karalabe): This needs a non-expiration method
continue
}
My understanding is that unreserve(peer.id) is used to reintroduce the unfulfilled requests back into the task queue when a request fails to be sent due to peer disconnection. Since the block height of these unfulfilled requests is guaranteed to be smaller than the current tasks in the queue, they should have the highest priority. In the next iteration of the loop, won't these unreserved requests be immediately picked up by other peers?
I would appreciate some clarification on the following points:
-
what “that is async” actually means in here, and what will it cause?
-
Could you provide more insights into why immediate pushing of unfulfilled requests is necessary in this context?