-
Notifications
You must be signed in to change notification settings - Fork 2.6k
network/service: Let get_value
return a future returning a DhtEvent
#3292
Conversation
So far to retrieve a value from the DHT, one would need to: 1. Trigger a DHT event query via `NetworkWorker.get_value`. 2. Somehow retrieve the event from `NetworkWorker.poll`, e.g. by having it return the responses as a stream. Instead of the above, this commit suggests having `NetworkService.get_value` return a future, eventually resolving to the DHT response. Internally this is coordinated via `futures::sync::oneshot`, maintaining a list of subscribers for a given DHT key, notifying each one when a new event comes in.
I really dislike the fact that polling the We used to have this kind of design in libp2p, and not doing so is what made libp2p robust. |
Today any logic interfering with
Can you reference an example where architectures like this caused issues? One thing to add is that @tomaka what would be an alternative interface for something trying to retrieve DHT events without access to I understand that this adds more complexity and possible failure scenarios to |
tbh I still have doubts that we need a |
Yes, that is for sure something we would need to clean up.
@montekki do you have an alternative approach for something trying to retrieve DHT events without access to |
Indeed, which is why I'm trying to remove the
This architecture is generally "fine" as long as you know that a future will not resolve unless another future is being polled. In practice, we often had to do things like
The point is that you should access |
How would "accessing" look like? Let's say a component x in crate y in
I am sorry for all the questions @tomaka. In case there is a design doc describing the architecture of the refactoring I would appreciate a pointer. Motivator for the discussions: I expect the logic I am adding in #3247 to grow in the future, enabling substrate to be smarter around which nodes to connect to, based on knowledge we can retrieve from the layers above. It is currently integrated into |
The HashMap that this PR adds would basically reside in the Service.
Like a lot of things that that we do in Substrate, unfortunately no.
That's decided by the |
And then inside Service we have a fn subscribe(self, hash: Mutlihash) -> impl Future<Item=DhtEvent, Error=_> How does that differ from the approach in this pull request apart from pushing the logic one level up into the Service instead of |
Keeping I am closing here in favor of the approach described above. |
So far to retrieve a value from the DHT, one would need to:
Trigger a DHT event query via
NetworkWorker.get_value
.Somehow retrieve the event from
NetworkWorker.poll
, e.g. by having itreturn the responses as a stream.
Instead of the above, this commit suggests having
NetworkService.get_value
return a future, eventually resolving to the DHT response. Internally this is
coordinated via
futures::sync::oneshot
, maintaining a list of subscribers fora given DHT key, notifying each one when a new event comes in.
Who needs this?
This would reduce logic needed in #3247, keeping network related code inside the
network module.
Future vs Stream?
When two users of the DHT interface trigger a query concurrently for the same
key and later on a response comes in, there is no way to tell which query this
response is responding to.
get_value
eventually returning a single value mighttrick a user into thinking that this is the response of their query.
Instead one could return a stream instead of a future. The downside of this
approach is added implementation complexity.
For #3247 a future is sufficient. My suggestion is to properly document the
case, and stick with returning a future for now. If there is ever the need for a
consumer to consume a stream instead of a future #3247 can be adjusted
accordingly.
@tomaka @montekki let me know if you think the idea of this draft is worth further investigating.