Lots of object models primarily track application state. For example, OkHttp’s Http2Connection.kt
has state for whether a ping’s reply is outstanding:
private var awaitingPong = false
This is set to true each time a ping is sent and then false again when its reply is received.
I’ve recently started to prefer models that primarily track facts instead. For example:
private var pingsSent = 0L
private var pongsReceived = 0L
The pingsSent
is incremented when a ping is sent and pongsReceived
is incremented when its reply is received. The state is a function of the two fields:
fun awaitingPong() = (pingsSent > pongsReceived)
Tracking facts is more code so I shouldn’t prefer it! But I do:
- There’s no lock shared between the thread writing pings and the thread reading their replies.
- When a reply is late the code can now report how many successes we saw before the failure.
- It affords more focus in tests.
I like event-driven architectures for microservices. It’s awesome how that strategy scales down to a single class.