Infrastructure code for managing RPCs that evolve over time to use different types at
different versions.
Three scenarios are supported:
The caller is responsible for managing versions and dispatches to callees that
are written in a version-oblivious way.
The proto-typical example of this scenario is a commander that needs to call out to
many assistants for that same system. In this scenario, the assistants each
implement a single version of the rpc and the commander has to take this into
account.
The callee is responsible for managing versions and callers need not bother
themselves with any versions.
The proto-typical example of this scenario is an assistant from one system calling
out the commander of another system. In this scenario, the assistants each know a
single version of the rpc to call and the commander has to implement them all.
Both caller and callee cooperate to decide which version to use, each one
being able to use some subset of all possible versions.
The proto-typical example of this scenario is when two systems developed
independently with their rpc types defined in some shared library that has yet
another independent rollout schedule. In this case one may roll out a new rpc
version (V) in the shared library (L) and then the caller and callee systems can each
upgrade to the new version of L supporting version V at their own pace, with version
V only being exercised once both caller and callee have upgraded.
In each scenario, it is desirable that the party responsible for managing versions be
coded largely in terms of a single "master" version of the types involved, with all
necessary type conversions relegated to a single module. Versioned_rpc
is intended
for implementing such a module.
Type coercions into and out of the model go in the directions indicated by the
following diagram:
Caller converts Callee converts
=============== ===============
caller callee
| callee | callee
| | caller | | callee
| | | | | |
,-->-- Q1 --> R1 -->-. Q1 -->-. | ,-->-- R1
/ \ \ | /
Q --->-- Q2 --> R2 -->-- R Q2 -->-- Q --> R --->-- R2
\ / / \
`-->-- Q3 --> R3 -->-´ Q3 -->-´ `-->-- R3