Volgt uit #4 en #5.
Probleem
simple_secure_chat bewaart zijn prefs als ruwe bytes. /node_prefs wordt in zijn geheel gelezen met file.read((uint8_t *) &_prefs, sizeof(_prefs)) (examples/simple_secure_chat/main.cpp:337) en in zijn geheel geschreven met file.write((const uint8_t *)&_prefs, sizeof(_prefs)) (main.cpp:356). Er staat geen versienummer of magic in de file, dus de layout is puur positioneel.
Daardoor kan een nieuw veld alleen uit de bestaande padding komen. In PR #5 is uint8_t dutycycle_auto (main.cpp:71) uit unused[3] gehaald, waar nu nog unused[2] van over is. Een file die voor die wijziging is weggeschreven heeft daar een 0 staan, want memset(&_prefs, 0, sizeof(_prefs)) (main.cpp:285) vulde de padding. Die 0 leest terug als "auto uit".
Voor de andere vier node-types is dat geen probleem. Die gaan via ConfigSerializer of via loadPrefsInt(), waar een ontbrekend veld op zijn struct-default blijft staan en dutycycle_auto dus op 1 uitkomt. Alleen simple_secure_chat migreert niet mee en blijft op zijn opgeslagen airtime factor tot iemand set af doet of de node reset.
Dat is voor deze ene wijziging klein, want het is een voorbeeld-sketch met alleen set af en geen set dutycycle. Het patroon zelf is het echte punt: elk volgend veld in die struct heeft dezelfde vraag, en zolang er geen versie in de file staat is het antwoord altijd "de oude bytes bepalen wat het nieuwe veld betekent".
Opties
- Een versiebyte of magic vooraan
NodePrefs zetten, en bij het lezen de velden per versie invullen. Bestaande files vallen dan in versie 0 en de code kan expliciet zeggen wat een ontbrekend veld moet worden. Dit lost het patroon op, niet alleen dit veld.
simple_secure_chat op ConfigSerializer zetten, zoals de andere node-types. Meer werk, maar dan verdwijnt de hele positionele layout en daarmee de klasse van problemen.
- Niets doen en per veld accepteren dat de padding-waarde de default wordt. Dan hoort er wel een comment bij de struct die dat vastlegt, zodat de volgende wijziging er niet in trapt.
Ik heb geen voorkeur zonder te weten hoeveel simple_secure_chat nog gebruikt wordt. Als het puur een voorbeeld is, is optie 3 met een comment verdedigbaar. Als er nodes op draaien, is optie 1 de kleinste die het echt oplost.
Vraag
Welke van de drie? Ik kan optie 1 of 3 oppakken. Optie 2 raakt meer dan alleen dit voorbeeld, daar wil ik eerst een 👍 op voor ik begin.
Volgt uit #4 en #5.
Probleem
simple_secure_chatbewaart zijn prefs als ruwe bytes./node_prefswordt in zijn geheel gelezen metfile.read((uint8_t *) &_prefs, sizeof(_prefs))(examples/simple_secure_chat/main.cpp:337) en in zijn geheel geschreven metfile.write((const uint8_t *)&_prefs, sizeof(_prefs))(main.cpp:356). Er staat geen versienummer of magic in de file, dus de layout is puur positioneel.Daardoor kan een nieuw veld alleen uit de bestaande padding komen. In PR #5 is
uint8_t dutycycle_auto(main.cpp:71) uitunused[3]gehaald, waar nu nogunused[2]van over is. Een file die voor die wijziging is weggeschreven heeft daar een 0 staan, wantmemset(&_prefs, 0, sizeof(_prefs))(main.cpp:285) vulde de padding. Die 0 leest terug als "auto uit".Voor de andere vier node-types is dat geen probleem. Die gaan via
ConfigSerializerof vialoadPrefsInt(), waar een ontbrekend veld op zijn struct-default blijft staan endutycycle_autodus op 1 uitkomt. Alleensimple_secure_chatmigreert niet mee en blijft op zijn opgeslagen airtime factor tot iemandset afdoet of de node reset.Dat is voor deze ene wijziging klein, want het is een voorbeeld-sketch met alleen
set afen geenset dutycycle. Het patroon zelf is het echte punt: elk volgend veld in die struct heeft dezelfde vraag, en zolang er geen versie in de file staat is het antwoord altijd "de oude bytes bepalen wat het nieuwe veld betekent".Opties
NodePrefszetten, en bij het lezen de velden per versie invullen. Bestaande files vallen dan in versie 0 en de code kan expliciet zeggen wat een ontbrekend veld moet worden. Dit lost het patroon op, niet alleen dit veld.simple_secure_chatopConfigSerializerzetten, zoals de andere node-types. Meer werk, maar dan verdwijnt de hele positionele layout en daarmee de klasse van problemen.Ik heb geen voorkeur zonder te weten hoeveel
simple_secure_chatnog gebruikt wordt. Als het puur een voorbeeld is, is optie 3 met een comment verdedigbaar. Als er nodes op draaien, is optie 1 de kleinste die het echt oplost.Vraag
Welke van de drie? Ik kan optie 1 of 3 oppakken. Optie 2 raakt meer dan alleen dit voorbeeld, daar wil ik eerst een 👍 op voor ik begin.