Multiple versions of roles
In what follows we expand the material provided in the configuration section of the component documentation, and the role definition section of the service app documentation.
Motivation
Kumori Platform manges the lifecycle of a deployed service. This includes changes in a deployment ranging from mere configuration parameter changes, to actual software updates changing the way a role is implemented.
Introducing upgrades to the implementation of roles is often best carried out through cautious progressive substitution of an implementation for another. Some strategies that may be followed are
-
Derive a percentage of the load to the new implementation, in order to observe its behavior, and potentially test it for potential problems not found during standard testing cycles.
-
Move concrete requests to new implementations of a microservice. Which requests should be sent to what versions is dependent on the client of the microservice. In order to make the decision, some sort of context information must be made available to that client.
In fact, case (1) above can be seen as a specialization of case (2), which is more general.
Kumori Platform covers both classes of usage by means of a tagging mechanisms expressed through the concept of version set's
Version sets
A version set (vset
) represents a microservice, potentially implemented using multiple variations of code.
As a microservice, a vset
defines a channel interface, as any artifact does in Kumori Platform.
The definition of the vset field is as follows
vset: [string]: {
srv: #MicroService // The collection of version sets
roles: [rn=#roles]: {
meta: {...}
for sn in srv.#servers_a {
map: "\(sn)": role[rn].artifact.description.srv.#servers | *sn
}
for dn in srv.#duplexes_a {
map: "\(dn)": role[rn].artifact.description.srv.#duplexes | *dn
}
}
}
Including a role in a vset implies configuring a field within the roles
field
of the vset with the name of the role to be added.
The value of that added field will itself be a structure with a meta
field, containing
the metadata that will be exposed to clients of the vset, and a map
field, relating
the server/duplex channels of the vset with the server/duplex channels of the role,
so that the names of the vset channels may differ from those of the roles in the vset.
By default the map is the identity.
When we presented how the topology of a service application was expressed in our model,
we introduced the usage of the connect
field. In that section, the connect
field was introduced as linking roles
in a given service, being consistent with our equating role
to microservice within a service application.
However, in our model a microservice is actually represented by a version set, which may aggregate multiple
roles. Thus, connect
actually acts by linking microservices represented by `vset`s through connectors.
Or, more precisely, connect links default vsets (vsets associated by default with roles) to vsets via connectors.
Roles and Vsets
Every vset
is composed by one or more roles
in a service application.
In order to make a role belong to a vset, the vset
field of the service must include the name
of the role within the field vsets
of its definition.
Given any role
in a service, Kumori Platform defines automatically a default vset
with its name,
containing only that role. It is not legal to explicitly define a vset
with the name of an existing role.
The namespace for vsets includes that of roles within a service application.
|
For any vset
, its channel interface must be specified explicitly. For each role
belonging to the vset a map
is defined mapping server/duplex channels in the vset
to those of the role.
If no map is specified, for a role, the role is assumed to have the same server7duplex channels as the vset. |
Roles in multiple vsets
Kumori Platform's allows a role to belong to multiple vsets
, although the usual case will see a particular role
belonging to just its own vset
, or, when actually participating of an upgrade strategy, belonging
to its own vset, plus another vset representing the microservice that is being upgraded.
Implementing automatic request routing to a vset
As seen previously, when launching an instance of a component,
file /kumori/config.json
contains metadata that helps the code in the component decide and discover what the
actual implementation of a target vset
it should use.
There are occasions when we want the process to be transparent to the actual code of such component, in order to implement policies that randomly reroute part of the traffic to the various roles behind a vset.
Kumori Platform suggests the usage of complement containers (sidecars) to take care of these scenarios proxying the requests of such a component. To support such scenario, Kumori Platform will also resolve the name of each client channel (without the tag), returning the address of a local interface (127.0.0.x, the x depending on the channel).
Then a daemon can be started binding to such local address, waiting for the requests from the main container. This daemon can actaully be started within a sidecar, making the process transparent to the code in the main container.
As sidecars get mapped the same configuration files as the main containers, the sidecar can then apply any routing policy it deems convenient (e.g., weighted random). If a request context can be made available as part of the call (as it may be the case when using http) then the routing logic can be coded within the sidecar, making it more maintainable as it will not require involving functional code in the main container of the component.