-
Notifications
You must be signed in to change notification settings - Fork 478
Decouple device implementations via smoltcp-device
#1080
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
base: main
Are you sure you want to change the base?
Conversation
668ef07
to
c89df35
Compare
88d2939
to
bb4b13d
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1080 +/- ##
==========================================
+ Coverage 80.33% 81.41% +1.08%
==========================================
Files 81 77 -4
Lines 24339 24015 -324
==========================================
+ Hits 19552 19553 +1
+ Misses 4787 4462 -325 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
The end goal of supporting multiple incompatible I don't think splitting off the crate I'm also not sure what exactly would happen if you released e.g. smoltcp 0.13 and smoltcp-device 1.0 today and then needed to do a breaking change and release smoltcp-device 2.0 tomorrow. What is the procedure for doing that? Does smoltcp itself have to care beyond bumping the version number of the smoltcp-device crate concurrently with a new smoltcp crate release? It sounds like the answer is "yes" since you want to support consumers that are lagging on a smoltcp 0.x version without any upgrades to them at all, meaning that if somebody pinned the patch version of smoltcp you'd expect that to still build and be usable in a project together with other users of the This sounds like a very significant maintenance and testing burden! Who are the people who can't update their smoltcp crate versions? Do they have money? Are they going to put that money towards maintenance? While I can't speak for @Dirbaio, I will not sign up to do this sort of release engineering without being very well compensated for it. |
Or to summarize in a single sentence: it sounds to me like this PR comes with an implied request to support a (partially sparse) N:M mapping of smoltcp-device API variants to smoltcp API variants, but why would we accept that? |
In that case we would need to implement support for If compatibility needs to be broken, we can handle that. The goal is to reduce the amount of times compatibility needs to be broken. Look at It's obvious that if a user is stuck with a smoltcp-device 1.0 implementation, they would be locked out of future smoltcp improvements. Just like they are right now, if their network device only implements smoltcp 0.11's Device trait. Supporting multiple versions of smoltcp itself isn't a big problem for us. We can easily create |
I'm not convinced it's obvious: right now smoltcp ends up being an implementation detail, a contract between two sub-components, and issues arise because there's a vesion disagreement. The problem of what to do in case of incompatibility doesn't go anywhere (the end user would still have to somehow figure out that it's a smoltcp version compatibility issue, get the dependency tree to be updated properly, etc), the only real difference with this proposal is that the frequency of this becomes much lower. I agree that this is desirable and that some sort of solution is needed! I'm just concerned about what happens when we bump the major of smoltcp-driver and the whole sub-ecosystem somehow breaks because people have made unsound assumptions. |
Anyway, let's discuss the possible implementation strategies:
It sounds like you're not actually interested in (3) so that's out. Personally I'm leaning towards (2) specifically because we are creating a new stable, versioned API surface. Workspaces and monorepos work well when you expect to be doing cross-cutting changes to many components at once. But we very much do not expect to be doing cross-cutting changes to smoltcp + smoltcp-device: if we did it would defeat the purpose of your request. Thoughts? |
I do think this is something we want to do. The "small crate with just the trait" has worked quite well in Embassy to ease the pain of releases, and the problem here is exactly the same. It makes me sad that the API surface of There's also the ipv4/ipv6 and medium Cargo features. which could cause trouble. If you enable
yes, the goal is just to reduce the frequency of breaking changes. If there's some legitimate need to change the driver contract we'd still change it.
This is what I'd do.
|
I agree with you (at least if I understood your stance on this correctly) that attempting this would be probably unreasonably difficult. I think only abandoned implementations would be left behind, the others should have a reasonable upgrade path.
This part worries me a bit. I agree we can remove the features, but I'd personally prefer adding new protocols/media to be a non-breaking change. I think the API can be formulated in a way to allow this. The feature problem could be split in two:
If these sets don't match, the driver crate can emit a nice build error. If the user naughtily enables a feature that shouldn't be, the build would fail in some other way, but that's the user's fault and problem. One thing that may go wrong, is multiple device implementors in a project. For example, esp-radio may provide a device that supports the ieee802154 medium, but the user may use an external ethernet chip, too, which doesn't. The two device impl crates should somehow end up building together without knowing about each other.
I don't have strong opinions about where the code should live, but a single repo is easier to work with when the device crate needs to be changed.
I'm not sure there is a way around DeviceCapabilities, it's after all a property of the underlying device. |
To clarify my position a bit: while it is difficult, the reason I don't want to do it is because I find it hard to believe that anybody will fund the development of the necessary infrastructure. If someone wants it enough I'm more or less completely fine with this proposal; I just don't want to have a half-baked version of it bitrotting for the next 5 years while becoming a major tech support problem.
To clarify my conclusions that I think are confirmed by this statement: Would you agree that the change we're discussing keeps the nature of the problem intact (crate with
To clarify my position here: I think it is not worth the complexity and headache (I think Cargo still can't quite manage features right when cross-compiling) to have features in smoltcp-device whose purpose is to make some transient data structures marginally smaller. I am not opposed to other modifications of the feature system being used, and I think the requires/provides system you're describing here is both novel and very promising. (At least, novel to me. If you've seen it in action that's even more interesting.)
As far as I understand, the fundamental point or the driving force of this PR is this exact situation: having two or more implementers. In light of this we should try to analyze the proposed system by assuming that there will always multiple incompatible implementers, otherwise we could easily miss some "rare" issues that in practice will be common because people don't necessarily upgrade their dependencies at any regular cadence, or sometimes ever. (Of course it should also work for one implementer, it goes beyond saying.)
I think if you are aiming for a separate and distinct public API you should "show your work" by doing the chnages separately; not because I want you to suffer but provides inherent validation of the case where mismatching versions of the library are present by way of procedure. It also makes it abundantly clear to contributors (and to some extent downstream users) that the crates are meant to change at their own separate timescales. (You could say that I want you to suffer exactly the same as external users would, though the idea is of course to make sure nobody involved suffers more than a trivial amount.)
Can you show me an example where simply using
What I meant is that I think all of the fields in
is that all? |
I understand and agree.
Just as Dario said above my comment, reducing the frequency of breaking changes is the goal, yes.
The part you're quoting is related to the provides/requires pattern. The point I was trying to make is that IF we decide to have media (or any other) features in the device crate, we'll have to make sure they are additive as they should be. Right now, the This may be an issue even right now, if implementor crates depend on smoltcp while enabling any of the
I don't think I understand what you are asking here. There are no problems with it, except that moving it out into the device crate is an unfortunate side-effect.
I'm not opposed to simplifying the problem. I agree with you that if the purpose of
Indeed, I should have even noticed this before opening this PR.
Updates:
|
a2c3a65
to
46fba9f
Compare
85a476b
to
42bf1ed
Compare
smoltcp-device
Gentle ping here :) We think this is a good idea, and the PR is now in a good spot (from our perspective). We'd be very open to helping with the maintence/infra, though I don't know how that would look. To reiterate, we're looking for solutions to avoid a million smoltcp X feature flags once we stabilize our wifi driver, this is just one solution which we think is a good one, and has proven to work well in embassy-net, but we're open to suggestions. |
This is a fairly low effort solution to #1010 mostly to try to motivate some discussion around this issue. The idea is that the Device trait, and everything around it might change less often than the smoltcp API surface and codebase. This means Device implementors can support multiple smoltcp versions with a single implementation - the biggest benefit is not being forced to react to breaking changes, unless they include changes to the device crate.
If the approach sounds viable, we can discuss how to make the split - whether the workspace approach is all right, or the device crate should live separately, is just a detail for me.