-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Fix: Ignore zero values when marshalling Limits. #1998
Conversation
Signed-off-by: Antonio Navarro Perez <[email protected]>
Zero means zero when inside the final struct used by go-libp2p. For example, when I start up a simple go-libp2p server and set When reading from JSON or This is pretty confusing. And I think we should have a way of defining not-set vs zero that is uniform across serialization.
No limits can be MaxInt32 and that should work fine. Is there some reason to prefer a special value? |
I think this change is pretty safe since it doesn't affect the semantics of the unmarshalled struct. What does this fix for you? I'm thinking of adding a "IsSetFlags" bit field to |
Hi @MarcoPolo! Answering your questions:
This is confusing for the final user. They think that they did something wrong, or that Kubo has a bug and the config overflowed.
It removes some confusion for the final user. If the user changes from Kubo CLI some RM param, there is no way to avoid serializing these other values as zeroes. And now that we know that zero means two different things depending on where the struct is read, it makes even more sense to apply this change to reduce the confusion.
Why not just use the language? If we use pointers, it is more idiomatic and easy to understand for the final user modifying the configuration, and for the developer implementing libp2p RM into other apps. IMHO, if a value is set to nil, should mean no limits for that value, and the upper scope will handle it. |
I originally thought that pointers would be needlessly slow for this since it would involve a pointer dereference every time you check a limit. I decided to fact check that thought by writing a quick benchmark (the benchmark is a bit contrived since I'm trying to avoid certain optimizations and avoid hitting cached L1/2 pointer values). The benchmark shows that while there is a bit of performance gain with flags, it's negligible. Especially with compiler optimizations. And it's a nicer experience to have a single value control whether something is set (nil or a number). So I'm in favor of using pointers here :)
I'm not sure I agree. Then there are two ways of defining a "big enough" value and no way of defining a "please use a default" value. I think nil should mean "this is unset, I don't care what this is, please use a default value", and a big number is how you define a big enough value. If you want this to appear simpler in the config, would it be better to write "Infinity" in the config and parse "Infinity" as a big enough value? Maybe we can make another type that would marshal as "Infinity" when |
Oof - so are we doing anything extra to make this even clearer (beyond what was done in this PR)? An issue I'm seeing here is that at least in the Kubo usecase of computing default limits and then applying user-supplied overrides is that there isn't a way for a user to set a limit to zero. If they do, it gets overridden by the computed default. Can we handle this better? |
Here's a PR in PR to at least make clear that we don't currently support 0-value user-supplied overrides: ipfs/kubo#9563 |
Fair enough :)
Sounds good. |
Continued in ipfs/kubo#9564 |
The changes around the config are in #2000 |
Ignoring zero values when marshaling zero values as it's done here https://github.com/libp2p/go-libp2p/blob/master/p2p/host/resource-manager/limit_defaults.go#L111
Outputs will change from:
to:
We need to confirm what zero means for Resource Manager. My understanding after asking @marten-seemann is that zero means zero, not infinite or not set.
If zero means zero, we need to specify a way to define no limits for some of the fields inside a BaseLimit or a BaseLimitIncrease object. We can use
-1
or use pointers to allownil
values.