Skip to main content

Internal Dcc Model Spc Version

This page describes how to maintain the native model, and highlights some potential pitfalls with the the cache.

SPC Version

All requests that are sent to the native core will be encoded as binary. The encoding is done with a specific SPC version. The range of supported versions are hardcoded in DccModel.Internal.SpcVersion

The native core might support a greater range of versions, but the Api and the backend will reject requests with unsupported versions, regardless of whether they understand the message or not.

When updating the native core, we can decide to update the supported versions as well. More info on that in the section "Maintaining SPC Version" below.

The following is how it is supposed to work when we reach production. At the time of writing this might not actually be the case though

Updating SPC Version

When an update is pushed to production, the backends will start to redeploy. Only once all backends have redeployed, the api-servers will redeploy.

This should ensure that a backend will never receive a message with an unsupported spc-version. There is a short window while the api-servers are redeploying where one api might report a higher supported spc-version to a client, which will then attept to use that version with an api-server that hasn't redeployed yet.

For now we accept this, and will assume the clients can just retry their request.

Maintaining SPC Version

All data that is sent to the native core is serialized with the DccModel.Internal.Serialization.DccSerializer class

The classes are either annotated with DccModel.Internal.Serialization.DccSerializableAttribute, or implements DccModel.Internal.Serialization.IDccSerializable.

For DccModel.Internal.Serialization.IDccSerializable please refer to documentation in code

The classes annotated with DccModel.Internal.Serialization.DccSerializableAttribute are expected to mirror the native classes. By annotating the members with DccDataAttribute serializers that can handle different spc message versions will be autogenerated.

For example. Given the following c++ class in the dcc, where a change is introduced in version 81, we would get:

class DccExample
{
int m_IntegerMember;
string m_StringMemberFromV81;
public:
void SPCCircumstances::Read(DCC::MessageIStream& mis)
{
int version = DCC::SPCMessageVersion::Instance()->GetCurrentVersion();
mis >> m_IntegerMember;
if (version >= 81)
mis >> m_StringMemberFromV81;
}
void SPCCircumstances::Write(DCC::MessageOStream& mos) const
{
int version = DCC::SPCMessageVersion::Instance()->GetCurrentVersion();
mos << m_IntegerMember;
if (version >= 81)
mos << m_StringMemberFromV81;
}
};

Mapped to c# we'd get

[DccSerializable]
class DccExample
{
[DccData]
public int IntegerMember {get;set;}

[DccData(MinVersion = 81)]
public string StringMemberFromV81 {get;set;}
}

If you update the supported range of SPC versions, make sure all data modelled in the global dcc is updated if it is affected by the newly available versions.

Known Problems

  1. Even if we redeploy all backends before any api-servers, there will be a window where the api-servers support different versions. This could mean that a client requests the highest supported version, and then starts using a version that isn't supported by all running api-servers which could lead to failures
  2. If we are running multiple client spc-versions there might be cases where distances cached for the older clients can't be used by the newer clients