Protocol
Versioning
Ankor has four parts that release separately: the @ankorcs/protocol package, the agent image,
the CS2 image and your controller. The protocol and both images share their major.minor, and
only their patch versions differ, so releases with the same major.minor work together under
SemVer. The protocol’s version decides whether two parts can talk.
Images explains the image tags and how a node moves between releases.
The protocol version
Every request between the parts carries the protocol’s version in the Ankor-Protocol HTTP
header. The value is the major.minor of @ankorcs/protocol, such as Ankor-Protocol: 0.9. These
requests carry it:
- the agent’s socket upgrade, event uploads and demo uploads;
- the setup script’s request for
agent.yml; - the plugin’s socket upgrade to its agent.
The receiver accepts a peer whose version has the same major as its own, at any minor. It answers
426 Upgrade Required to any other. This holds for 0.x too, so a breaking change goes to the
next major there as well.
The receiver can keep the peer’s version. A controller then knows which features each node has.
What a release may change
| Change | Release |
|---|---|
| A new optional key | Minor |
| A new request type | Minor |
| A new message or gameplay event that is not a request | Minor |
| A new enum value | Major |
| A new required key, or a key that is removed or renamed | Major |
| A key or value whose meaning changes | Major |
A new enum value is a major, because an older receiver rejects a value it does not know.
Receiving from a newer peer
Between compatible versions, a peer may be on a newer minor than the receiver. The controller, the agent and the plugin each handle what they do not know in the same way:
- A key the receiver does not know is ignored.
- A request whose
typeit does not know is answered withunsupported_request. - Any other message or gameplay event whose
typeit does not know is skipped, and the type is logged once. - A skipped gameplay event still takes its sequence number, so its server’s stream has no gap.
In a controller
- Check
Ankor-ProtocolwithisCompatibleProtocolfrom@ankorcs/protocol/helpers, and answer426when it fails. Keep the node’s version fromprotocolVersionOf. - Read the agent’s frames with
@ankorcs/protocol/session. It returnsunsupportedfor a message that this version does not have. Skip that frame instead of reporting an error. - In an event upload, test each event with
unknownMessageType(PluginToControllerMessage, frame.event). Count theseqof an unknown event as received, and store or quarantine nothing of it. - Read an
unsupported_requestreply as a node that does not have the feature yet. Offer a feature only on nodes whose protocol version has it.