-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: proxy all types of delegated routing #23
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for starting this 🙏.
Figure out why the network on my laptop stops working properly if I have this turned on for a few minutes.
My guess is running the accelerated dht client isn't making your router happy, but it has some QoS protections (like per-device limits) to protect your devices from each other. You can use a cli flag to enable/disable the accelerated DHT client and you should see if that makes the difference for you.
server_routers.go
Outdated
type parallelRouter struct { | ||
routers []server.ContentRouter | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code seems complicated enough that we should have some tests. The code looks similar to the go-libp2p-routing-helpers code so might be you can crib tests from there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still have to add more tests. It's not as easy to port the tests from libp2p as I thought
Edit: seems to be the case. |
it, itErr := call(ri) | ||
|
||
if itErr != nil { | ||
err = errors.Join(err, itErr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how are you thinking we're going to detect errors (e.g. with cid.contact) in prod? e.g. should we be logging from here or within one of the other packages? Does sending an error back along with the results make sense or will that cause problems?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I would always prefer that the caller handles the errors. Unfortunately, Boxo's server implementation ignores closing errors:
- https://github.com/ipfs/boxo/blob/08959f281f866bd4197b40bc90cf75c2828c07f0/routing/http/server/server.go#L351
- https://github.com/ipfs/boxo/blob/08959f281f866bd4197b40bc90cf75c2828c07f0/routing/http/server/server.go#L495
So we'd probably have to add it here if we want them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair, does that mean we should be doing some logging in the meanwhile as a sanity check around cid.contact errors?
return mi.its[mi.next].Val() | ||
} | ||
|
||
func (mi *manyIter[T]) Close() error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May not really matter here (and might not be required if the semantics of iter.Close
are intentionally loose), but is calling Next()
after Close()
supposed to work or not?
Doesn't seem like you need to worry about concurrent reads+closes (https://github.com/ipfs/boxo/blob/08959f281f866bd4197b40bc90cf75c2828c07f0/routing/http/types/iter/iter.go#L6), but not sure if all implementations are supposed to follow a similar pattern to https://github.com/ipfs/boxo/blob/08959f281f866bd4197b40bc90cf75c2828c07f0/routing/http/types/iter/json.go#L55
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May not really matter here (and might not be required if the semantics of
iter.Close
are intentionally loose), but is callingNext()
afterClose()
supposed to work or not?
As far as I understand, yes. The documentation states Next sets the iterator to the next value, returning true if an attempt was made to get the next value.
, which for me reads that: after Close
, Next
will always return false as it does not make an attempt to get the next value.
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #23 +/- ##
=========================================
+ Coverage 0 23.67% +23.67%
=========================================
Files 0 5 +5
Lines 0 583 +583
=========================================
+ Hits 0 138 +138
- Misses 0 440 +440
- Partials 0 5 +5 ☔ View full report in Codecov by Sentry. |
8cde154
to
1975da4
Compare
- use WaitGroup and select for ctx.Done() - call .Val right after .Next inside Goroutine
@aschmahmann I've added some tests. They're a bit more basic than the ones we have in https://github.com/libp2p/go-libp2p-routing-helpers, but they should cover enough for now. I think I addressed all the feedback. I extracted the local storage to a separate issue to tackle in a different PR. |
Ping @aschmahmann |
new ping for @aschmahmann ;) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies for the delay here @hacdias and thanks for the pings + callouts. Made a few relatively small comments but should be good to go otherwise.
If after the changes you're blocked for me on review just ask @Jorropo to review. I'd expect the changes here should be pretty small an easy for me to review though so he doesn't have to load context into the whole PR.
it, itErr := call(ri) | ||
|
||
if itErr != nil { | ||
err = errors.Join(err, itErr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair, does that mean we should be doing some logging in the meanwhile as a sanity check around cid.contact errors?
server_routers.go
Outdated
mi.done = true | ||
mi.wg.Wait() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like there might be a race here. For example: assume the context passed to newManyIter
never gets cancelled, but:
it.Next
returns true in thenewManyIter
goroutine but the select statement hasn't finished yet- The user calls
it.Cancel
- The
it.Cancel
call is blocked onwg.Wait
because it'll never be possible to readit.val
intomi.ch
One way to fix this is to add a cancel
func to the struct that's tied to the context (via context.WithCancel()
) and call that before triggering the Wait
.
I'm missing something but it seems this code is duplicated from |
It isn't. It can't be used directly. I had to make many changes. It simpler in many ways. We've discussed this before - perhaps only in calls. It wasn't possible to reuse the libp2p router helpers. I'm merging this as per @aschmahmann approval. We can iterate later. |
This is my initial version of the "everything bagel" for
someguy
: proxy everything we get from other sources and spit it back when asked. I did not use that much code fromgo-libp2p-routing-helpers
however. Our Delegated Routing stuff uses iterators, while libp2p relies on channels. Makes it very hard to re-use most of the code.To Do
Local storage for local caching purposes(Extracted to Local storage for local caching purposes #25)cc @aschmahmann