ndsev / zserio-tutorial-python

Python tutorial for the zserio serialization mechanism
BSD 3-Clause "New" or "Revised" License
4 stars 0 forks source link

backward-compatible thrown exception #1

Open sduwall opened 2 years ago

sduwall commented 2 years ago

first version zs content:

package tutorial;

struct Employee
{
    uint8           age : age <= 65; // max age is 65
    string          name;
    uint16          salary;
    Role            role;
    // if employee is a developer, list programming skill
    Experience      skills[] if role == Role.DEVELOPER;
};

struct Experience
{
    bit:6       yearsOfExperience;
    Language    programmingLanguage;
};

enum bit:2 Language
{
    CPP     = 0,
    JAVA    = 1,
    PYTHON  = 2,
    JS      = 3
};

enum uint8 Role
{
    DEVELOPER = 0,
    TEAM_LEAD = 1,
    CTO       = 2
};

struct ArrayEmployee
{
    int16   numItems;
    Employee list[numItems];
};

second version zs content:


struct Employee
{
    uint8           age : age <= 65; // max age is 65
    string          name;
    uint16          salary;
    Role            role;
    // if employee is a developer, list programming skill
    Experience      skills[] if role == Role.DEVELOPER;

    optional uint16 bonus;
};

struct Experience
{
    bit:6       yearsOfExperience;
    Language    programmingLanguage;
};

enum bit:2 Language
{
    CPP     = 0,
    JAVA    = 1,
    PYTHON  = 2,
    JS      = 3
};

enum uint8 Role
{
    DEVELOPER = 0,
    TEAM_LEAD = 1,
    CTO       = 2
};

struct ArrayEmployee
{
    int16   numItems;
    Employee list[numItems];
};

problem description:

  1. serialize array employee used second version zs
  2. deserialize array employee used first version zs
  3. raise zserio.PythonRuntimeException
  4. How to solve the problem?
  5. How to keep backward-compatible?
mikir commented 2 years ago

I think the problem is that optional put hidden boolean to the serialized bytes. This hidden bit should be reflected in the first version as well:

struct Employee
{
    uint8           age : age <= 65; // max age is 65
    string          name;
    uint16          salary;
    Role            role;
    // if employee is a developer, list programming skill
    Experience      skills[] if role == Role.DEVELOPER;
    bool            hasBonus; // should be always false in the first version
};

More info about hidden data in zserio can be found here.

I hope, it helps.

sduwall commented 2 years ago

thank you for your answer. but this has a problem, because the first version dose not know the hasBonus.

mikir commented 2 years ago

This should not be a problem because hasBonus should be always set to false. It can be renamed to dummy as well:

struct Employee
{
    uint8           age : age <= 65; // max age is 65
    string          name;
    uint16          salary;
    Role            role;
    // if employee is a developer, list programming skill
    Experience      skills[] if role == Role.DEVELOPER;
    bool            dummy; // should be always false in the first version
};
sduwall commented 2 years ago

Thank you for your answer.

This maybe cannot solve the problem, because i cannot know the hasBonus field. After several months, this field needs to be added according to business needs. But now the first version has been sent out and cannot be modified. So reading the latest data with the first version engine will crash.

mikir commented 2 years ago

OK, I see. Unfortunately, there is currently no solution for that.

However, we have an issue in backlog because of that: https://github.com/ndsev/zserio/issues/43. You might put there some requirements.

sduwall commented 2 years ago

OK, thank you for your timely answer too much.