rolandweber / Pityoulish

A collection of programming/debugging exercises to support a course on Distributed Systems.
Creative Commons Zero v1.0 Universal
7 stars 0 forks source link

Encapsulate logic to detect the end of PDUs received via sockets #13

Closed rolandweber closed 6 years ago

rolandweber commented 8 years ago

Classes SimplisticSocketHandler on the server and MsgBoardClientHandlerImpl on the client are supposed to be independent of the wire format. They use helper objects for parsing the received PDUs. However, both classes implement some limited TLV parsing in order to detect when a full PDU is received. Ideally, these classes should work without changes if the wire format is changed, for example to JSON instead of TLVs. Refactor the code to detect PDU boundaries. Implement a helper that can be used on both the server and the client. Keep the interface independent of the current TLV encoding. While TLVs provide the length of the PDU in the header, other formats might not. The helper should work equally well with blocking IO and asynchronous NIO.

rolandweber commented 8 years ago

General idea: For each incoming PDU, instantiate a stateful helper object. It gets access to the data received so far, and updates when more data comes in. It can tell:

  1. Whether the PDU is complete, or some data is missing yet.
  2. Where the PDU ends, once it is complete. The beginning of the next PDU might have been received already.
  3. Optional: how much more data is expected. Useful to verify or adjust buffer sizes.
  4. Whether the data is totally screwed up and the connection should be dropped.

There should be a factory interface to instantiate the helper. The factory is stateless and passed to the code that receives data. The helper itself is stateful, so that it can keep track of partially processed PDUs. In the case of TLVs, it can compute the length of the PDU once, as soon as the first four bytes are available.

Tracking data about partially received and processed PDUs isn't that important for TLVs. Computing the length from the two bytes in the header requires no significant effort. For the API design, however, it is important to keep the receiving classes and the interface of the helper independent of the wire format.

Imagine that the wire format is JSON. There is no header with a length. The logic must process JSON data and keep track of how many braces, brackets, double quotes, and escape sequences still need to be closed before the PDU is complete. You wouldn't want to process the JSON data from the start again every time a few more characters have been received. Therefore, the API must allow for stateful helpers.

In the JSON case, it would actually be helpful to fully parse the received data along the way, and then use it without parsing it again. Maybe an API for only detecting the end of a PDU, without parsing it, is not such a good idea after all? Implement a stream parser for PDUs instead?

rolandweber commented 6 years ago

YAGNI