Skip to content

fix(iota-indexer): deadlock when fetching from HttpRestKvClient in some scenarios #9508

@sergiupopescu199

Description

@sergiupopescu199

The deadlock issue is originated from this method when we provide as input an empty vector :

async fn multi_fetch(&self, uris: Vec<Key>) -> Vec<IndexerResult<Option<Bytes>>> {
        let len = uris.len();
        let fetches = stream::iter(uris.into_iter().map(|url| self.fetch(url)));
        fetches.buffered(len).collect::<Vec<_>>().await
}

This is because of buffered(len) which in this case is 0, it adds a side effect. By checking the buffered implementation I noticed that internally the len value is mapped to *this.max, so the while loop will not be executed halting the whole process since no futures are polled.

 // First up, try to spawn off as many futures as possible by filling up
 // our queue of futures.
 while this.in_progress_queue.len() < *this.max {
      match this.stream.as_mut().poll_next(cx) {
           Poll::Ready(Some(fut)) => this.in_progress_queue.push_back(fut),
           Poll::Ready(None) | Poll::Pending => break,
      }
 }

As a solution we could return early if we receive and empty vector or the buffered len we provide as a constant in the multi_fetch method.

Metadata

Metadata

Labels

infrastructureIssues related to the Infrastructure Team

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions