Implemented
Main
: Ripple Main
application which starts the Ripple platform.
Extension
(alias Extn
): Runtime dynamically linked libraries built using Ripple SDK, Main
loads these libraries during startup to offer enhanced capabilities.
ExtnCapability
: Current implementation of identifying and encapsulating a function of a given extension. ExtnCapability has an anatomy of ripple:[channel/extn]:[ExtnClass]:[service]
ExtnClass
: Classifies a given capability by mapping it to a functional Ripple unit like Device, Launcher, Distributor etc
IEC
: Inter Extn Communication implemented through the ExtnClient
Current Implementation of the Ripple Extensions have raised the following concerns.
For easier linking and references we are going to denote the problems with a P: [A-Z](n)
notation.
Better extension bundling strategies needed for scalability and standardization of the platform.
Capabilities are not well defined and overloaded with both identification and ExtnClass
mapping.
Arbitrary capabilities defined by each extensions leading to ambiguity, security and other long term issues.
Open-ended design of the capabilities which do not enforce distributors to implement required capabilities within the Ripple platform.
Non robust implementation of proprietary Device Extensions which have a ambigous input and output schema definitions leaving room for scalability, standardization and security issues.
Proprietary Device Extensions having to make multiple hops to reach the device channel and restricting Distributor developers with their custom implementation.
There were many approaches discussed to tackle this problem
For easier linking and references we are going to denote the approaches with a A: n
notation.
Moving device/channel
cargo workspace from an Extn
to a library and move the Device
connection layer into the distributor.
Current version of ripple has 3 layers
Main
- startsDevice
andDistributor
Device
- which connects to the device using a channel for device operations.Distributor
- which encapsulates the distributor operations.
This approach requires device/thunder
to become a crate library instead of an extension library.
This approach tries to move the Device
layer and move it into the Distributor
.
There are multiple issues with this approach first off separation of concerns between a Distributor
and Channel
will be removed.
Thunder
as a library crate still feels very appropriate to be used as a viable solution.
Uses Ripple Contract as a mechanism to deal with ambiguity and enforcement.
A concrete unit of work expected to be available through extensions. These contracts are not bound to a particular ExtnClass or ExtnType. Depending on a distributor implementation this contract can be fulfilled from a. Device Extn b. Distributor Extn/Channel c. Combination of a Device + Distributor Extensions
Ripple mandates set of contracts to be fulfilled by the Extn(s) on load. This helps Main
to identify, catalogue and apply permissions within IEC. If contract fulfillments are not met by Extn(s) it leads to a fatal bootstrap error.
ExtnCapability | RippleContract |
---|---|
Extension Identifier which classifies itself based on ExtnType which can be Channel or Extn and ExtnClass which classfies it further on how its applied. Finally it has an open ended service which is defined as per the Extn manifest. | Ripple Capability are contracts required by the Ripple Platform which are mandated to be implemented by the Distributor through their extensions. These are pre defined and will lead to bootstrap errors when not implemented. |
Open Ended Enumeration like ripple:extn:device:[session] , ripple:extn:distributor:[session] |
Closed Enumeration like Session |
Has a predefined role and lifecycle to run within certain expectations based on it ExtnClass and ExtnType | Needs to be registered by the Extensions and lifecycle will be based on the registered extension |
Supports Main in understanding the routing of a given extension during the Extension Client processes | Supports Main in identifying the extension which registered for the Ripple Capability |
Every library has its symbols defined as ExtnMetadataEntry
, in this new approach this entry will contain a provides
value which denotes the contract.
Overall this design addresses major concerns and can be used for some of the Problems with ExtnCapability
Following decision drivers are proposed for solution
Solves P: A
Current implementation of Extn
has a one to one mapping with a channel or extn. This doesnt scale as distributors would be expected to create multiple repos for fulfilling their contracts.
Builders will be of many types depending on their purpose
- ChannelBuilder - Builds
ExtnChannel
- JsonRpseeBuilder - Builds rpc extensions for Firebolt gateway
There could be may more such builders in near future.
Solves P: B
As explained here, ExtnCapability
is actually playing the role of identifier for an extension with the open-ended service. Overloading this with the ripple capability was the reason many of the above problems have araised.
With this change we have a better purpose and clarity for ExtnId
where it will be used for
- IEC to discover and delegate messages across the Extn spectrum
- Applying permissions based on the
ExtnManifest
This section covers these problems in detail
Solves P: C2
This was covered as the outcome for A: 1.Thunder library crate can be used by Distributor developers to create a Proprietary channel with their own thunder connection. This removing the need for Open ended capabilities or contracts causing P: B1.
There are many impacts to the Ripple code with this proposal, they are listed below:
Current implementation of Ripple uses these below Channels during bootstrap in ExtnState
Device
ChannelLauncher
Channel
Proposal expects Channel to be available from a builder, so the current bootstrap process needs to be updated to use ExtnChannelBuilder
and then build ExtnChannel
(s)
Proposal expects Device channel to be plural in nature to support Proprietary
Extns which can certainly be device channels as well.
So during LoadExtensionMetadataStep
in bootstrap Main
will identify the DeviceChannel(s)
and keep them in a separate vector.
All other channels will be in a separate vector.
Bootstrap would start the DeviceChannel
(s) and then start all of the other channels.
ExtnClient
currently uses the top level ExtnClass
and ExtnType
to identify a Async Channel sender to pass on the message to the extension. For eg ripple:class:device:thunder
it uses the key class:device
to store a value of Async Channel Sender.
This logic would now change to 2 levels of mapping
- Map<ExtnId,Async Channel Sender> - To store the Extn Id to cross beam sender mapping.
- Map<Contract,ExtnId> - To help reduce duplication of Async Channel across multiple redundant key values for similar contracts like device:info, device:windowmanager and other OSS RDK services
ExtnPayloadProvider
would change the method signature to fulfillment of contract rather than discovery of ExtnCapability.
For eg when a Request processor is added to a client. Client will send this RippleContract
as a ContractStatus
back to Main
. This will help Main
enforce contracts and provide fatal errors.
Reusable code like ThunderClient
, ThunderPool
and ThunderState
bootstrap logic will be moved into a reusable library. device/thunder
will only have the processor and ExtnChannel
logic such that a distributor can reuse all the components to quickly add support for their own proprietary Thunder extensions.
Launcher will be started along with other deferred Channels
after the Device ExtnChannel
is started up. Current code of launcher will be updated to not start the launching of the app on startup and it will rather wait for an event from Main
to start the launch process.
Applying all the above changes Ripple architecture would look something like below.