ipfs / helia-delegated-routing-v1-http-api

The Routing V1 HTTP API powered by Helia
Other
3 stars 4 forks source link

Helia makes duplicate (delegated) routing calls #148

Closed 2color closed 3 weeks ago

2color commented 1 month ago

What's the problem

Helia makes a content routing call per block broker.

For example, given the following (see running example):

// Create helia without connecting to any bootstrap peers
const helia = await createHelia({
  routers: [delegatedHTTPRouting('https://delegated-ipfs.dev')],
  blockBrokers: [
      trustlessGateway(),
      bitswap()
   ],
  libp2p: {
    peerDiscovery: []
  }
})

const fs = unixfs(helia)
const stats = await fs.stat(CID.parse('bafybeicklkqcnlvtiscr2hzkubjwnwjinvskffn4xorqeduft3wq7vm5u4'))

Helia will make two HTTP calls to the delegated routing endpoint and one will be cancelled.

Reproductions

How it happens

In trying to understand how this happens, I've been able to establish the following (from a Verified Fetch example with creates a session):

  1. NetworkedStroage.get() (blockstore) get is initially called by unixFsResolver and calls `raceBlockRetrievers
  2. NetworkedStroage.raceBlockRetrievers() calls retrieve for each blockBroker
  3. For the trustlessGateway broker, TrustlessGatewaySession.findNewProviders() gets called, which gets routing passed in and make a delegated routing call.
  4. For the Bitswap broker, BitswapSession.findNewProviders() gets called, which gets routing passed in and make a delegated routing call.

In other words, each block broker makes the same routing call.

Open questions

achingbrain commented 1 month ago

As you've found it's the block brokers that are making the routing calls. This is because each block broker does it's own thing to fetch blocks and there's no coordination between them.

One router will be faster than the other, and the outstanding request is cancelled when the other resolves.

We could have the delegated http routing implementation guard on parallel concurrent requests to the same URL with the same query parameters and also store the response in the browser's cache if available?

It's also worth noting that you probably don't need to configure delegatedHTTPRouting as a router with createHelia as above since an instance of DelegatedRoutingV1HttpApiClient is already configured as a libp2p service, which the trustless gateway block broker will invoke via the helia routing (since it invokes the libp2p routing).

2color commented 1 month ago

We could have the delegated http routing implementation guard on parallel concurrent requests to the same URL with the same query parameters and also store the response in the browser's cache if available?

As discussed in person, we will probably take this approach.