In a client library reading TCP, there are constraints.
- Latency:
- up <- larger frames, more batching
- down <- smaller frames, send without waiting in buffers, disable nagles' algorithm
- Throughput:
- up <- larger frames, more batching
- down <- smaller frames, less batching
- Slow connections:
- better to act on smaller data that can be deserialised than wait for full batch, partial evaluation, piecewise deserialisation
- Ephemeral state handling, needs deciding per operation/command/query:
- handling broken sockets by reconnecting
- handling broken sockets by throwing exception upwards
- handling timeouts, w/ retry
- handling timeouts, w/ higher level logic deciding to perform another operation/diff. connnection
- Slow consumers:
- signalling rate of consumption to rate of fetching, feedback loop - consumers less granular than 'tcp buffer'
- Exception handling:
- In framing layer, single exception for decoding errors - deserialisation problem or corrupt data
- In framing layer, single exception for encoding errors
- In framing layer, single exception for security error
- In channel layer, single exception for broken channel (idempotent operation failed)
- In channel layer, single exception for broken channel (non-idempotent op failed, e.g. transaction w/ Id that needs to be retried)
- In consumer/app layer having a collection of policies wrapping the above exceptions to implement a sane policy. Aim: idempotent treatment/function application on data
- Stream transducing:
- Fetching raw bytes from socket ~> CRC32 start ~> deserialise || CRC32 step ~> CRC32 finalise ok ~> pass full message to channel layer | refetch corrupt message (policy, retries 3, then exception) ~> decrypt step || HMAC step ~> decrypt finalise ok ~> HMAC finalise ok | throw exception, move to poision message queue ~> pass to app layer | ignore message, is not for me ~> apply app f-n on message | fail, move to poison queue 2 ~> mark as seen
- As this is going on, next message is being fetched
- Each step acts on a window of data, size of these windows is an optimisation problem
- Stepwise algorithms can be fed same data concurrently CRC32, or simply in steps as data becomes available, like a CBC cipher
- Some steps break the flow, like the verification steps