lazyengineering / faststatus

Simple API for sharing if a resource is free, busy, or very busy
MIT License
1 stars 2 forks source link

Implement binary marshal/unmarshal #12

Closed jessecarl closed 7 years ago

jessecarl commented 7 years ago

Implement the binary marshal and unmarshal methods. In order to send, receive, and store efficiently, a custom binary format would be useful. It would especially be useful for communicating with clients in other languages. It should be able to be parsed quickly in most languages.

jessecarl commented 7 years ago

Consider the following:

jessecarl commented 7 years ago

Need to consider the testing strategy we want to employ. I'm inclined to emulate the strategy employed by the time package: test Marshal to Unmarshal, test known bad Marshal, and test bad Unmarshal.

jessecarl commented 7 years ago

Let's consider using the following for the magic numbers in our format here: 0x90,0xe9 I'm sure I'm not the only one to use two consecutive Fibonacci numbers like 144,233, but I couldn't think of anything better.

jessecarl commented 7 years ago

My current thinking:

jessecarl commented 7 years ago

This is probably more costly than a naive implementation. The addition of magic bytes provides a quick check that the message is supposed to be a Resource. The version, which may be split in order to provide distinct actions (New, Save, Fetch, etc.) allows a decoder to know how to handle the rest of the message. Put the length of the FriendlyName in the header because it is the only variable-length property of the Resource. Do a simple XOR checksum of the header so far for a quick sanity check. Add some padding to the end of the header as another sanity check, allowing the message itself to start after exactly eight bytes. After the message data, add the Adler-32 checksum for a final sanity check and a maximum message size of 256 bytes.

Again, this is probably overkill for most applications, but the binary format is most likely going to be used on less reliable hardware and networks in embedded devices.

jessecarl commented 7 years ago

Instead of the Adler-32 checksum, which is not ideal for small messages, use CRC32 instead. With a message this small, speed shouldn't be much of an issue.

jessecarl commented 7 years ago

Step back a second.

We'll likely implement an adapter for the formats that require all this extra stuff. I'm going to pull this back again.

A second proposal:

I think this should provide a compact, easy to parse message.

jessecarl commented 7 years ago

Testing contract:

For MarshalBinary (independent of UnmarshalBinary):

For UnmarshalBinary (independent of MarshalBinary):

For MarshalBinary together with UnmarshalBinary:

jessecarl commented 7 years ago

Tests still need to be added to verify a few edge cases and invalid properties.

jessecarl commented 7 years ago

I completed a few additional test cases for bad data.