You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm closing these way-outdated (draft) PRs and consolidating the ideas into a more coherent proposal here.
Button nanoservices #518: button services refactor in the service list to split the monolithic button into a register layer, edge layer, and click layer
Also related to the adapters discussion from #495, since adapters are one mechanism for making this all work.
Nanoservices by Example: the Button
The current button service is a bit monolithic: it's got the polling / streaming pressure register, up / down / hold events, and support for analog buttons, all in one service. It seems to be mixing a bunch of stuff that often gets used together, but is somewhat orthogonal:
The basic digital switch.
Up/down events to reduce bus bandwidth (instead of streaming the register).
Analog buttons, that can be used as regular buttons (such as with thresholding).
So one idea would be to separate everything (as proposed in #518):
The basic digital button and its streaming register
An edge detection adapter that reads that register, and provides edge events
Upper-level adapters, for example click / click-and-hold / double-click gesture detection - services that get closer to the application layer so the end user can directly use them, instead of writing their own click detectors.
A separate analog button service - with adapters to allow it to be used-as a digital button
Other related services that can be used-as a button can also provide adapters to the click / gesture service - for example, capacitive sensors
There are good reasons for this monolithic approach (see the performance section below), and more thought is needed to figure out how to address these concerns in a nanoservices approach (if it's even possible).
User-facing benefits
One advantage is having services be tight to the hardware - for example, a analog pressure register kind of makes sense for a digital button (in the sense that 0.0 and 1.0 are valid values), but it's not something that will be fully supported (nothing between 0.0 and 1.0 will ever be used). Under this proposal, the service closely describes the hardware, but also allows these used-as relationships through adapters.
Tooling in the programming environment can then help surface the available adapters from currently connected hardware. These adapters could be written as VM programs, allowing them to run anywhere. These adapters also allow extensibility beyond what would have been supported in the original firmware (or what would have even existed when the original firmware was written).
Note: VM programs that consume services and provide other services (already implemented) can address the extensibility and upgradability use case without a nanoservices approach.
Related is that some services (like the traffic light and gamepad) are effectively composition services (the traffic light contains 3 LEDs, while the gamepad contains buttons and joysticks), though they are greater than just the sum of their parts. Adapters can allow a bundling and unbundling of constituent services, though perhaps there should also be some builtin composition support.
Dealing with performance
There are (at least?) two reasons we have monolithic services:
we can't define more services on cheap micros
we want to minimize bus traffic - for example, in the button edge detection example, we don't want to stream registers over the bus if we can run the edge detector locally
For the first: perhaps nanoservices might be more about the user-facing programming abstraction rather than the underlying bus communications. Perhaps it makes sense to separate the bus communication format from the user-facing devices, so each can optimize for different things (not sure what this would look like, and whether this is even possible)? There might be other ideas here too.
For the second: there's discussion of tier-splitting with where VM programs run - for example, if the micro on the button was sufficiently powerful enough, it can run VM programs like the edge detector, and register reads could happen locally, without spamming the bus. Or, maybe these adapters can be baked into the base firmware (for example, if VM programs can be compiled down into firmware, especially on micros not powerful enough to run a full VM), so the module developer can pull off-the-shelf adapters and only needs to worry about implementing the lowest hardware abstraction layer.
There's a deeper feasibility discussion in #518, which also looks at an inheritance structure as another potential solution.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
I'm closing these way-outdated (draft) PRs and consolidating the ideas into a more coherent proposal here.
Also related to the adapters discussion from #495, since adapters are one mechanism for making this all work.
Nanoservices by Example: the Button
The current button service is a bit monolithic: it's got the polling / streaming pressure register, up / down / hold events, and support for analog buttons, all in one service. It seems to be mixing a bunch of stuff that often gets used together, but is somewhat orthogonal:
So one idea would be to separate everything (as proposed in #518):
There are good reasons for this monolithic approach (see the performance section below), and more thought is needed to figure out how to address these concerns in a nanoservices approach (if it's even possible).
User-facing benefits
One advantage is having services be tight to the hardware - for example, a analog pressure register kind of makes sense for a digital button (in the sense that 0.0 and 1.0 are valid values), but it's not something that will be fully supported (nothing between 0.0 and 1.0 will ever be used). Under this proposal, the service closely describes the hardware, but also allows these used-as relationships through adapters.
Tooling in the programming environment can then help surface the available adapters from currently connected hardware. These adapters could be written as VM programs, allowing them to run anywhere. These adapters also allow extensibility beyond what would have been supported in the original firmware (or what would have even existed when the original firmware was written).
Note: VM programs that consume services and provide other services (already implemented) can address the extensibility and upgradability use case without a nanoservices approach.
Related is that some services (like the traffic light and gamepad) are effectively composition services (the traffic light contains 3 LEDs, while the gamepad contains buttons and joysticks), though they are greater than just the sum of their parts. Adapters can allow a bundling and unbundling of constituent services, though perhaps there should also be some builtin composition support.
Dealing with performance
There are (at least?) two reasons we have monolithic services:
For the first: perhaps nanoservices might be more about the user-facing programming abstraction rather than the underlying bus communications. Perhaps it makes sense to separate the bus communication format from the user-facing devices, so each can optimize for different things (not sure what this would look like, and whether this is even possible)? There might be other ideas here too.
For the second: there's discussion of tier-splitting with where VM programs run - for example, if the micro on the button was sufficiently powerful enough, it can run VM programs like the edge detector, and register reads could happen locally, without spamming the bus. Or, maybe these adapters can be baked into the base firmware (for example, if VM programs can be compiled down into firmware, especially on micros not powerful enough to run a full VM), so the module developer can pull off-the-shelf adapters and only needs to worry about implementing the lowest hardware abstraction layer.
There's a deeper feasibility discussion in #518, which also looks at an inheritance structure as another potential solution.
All reactions