Deepening the design of our walking skeleton by introducing asynchronous messages for transaction commit requests.
2011-10-08
2011-10-02
Let's Code Dimdwarf #68: Session API
Deepening the design of our walking skeleton by creating the application API for sending and receiving session messages.
2011-09-28
Let's Code Dimdwarf #67: Hide SessionHandle
The ClientSessions
class is good enough for now, so we can resume doing what initially caused the need for it; we need to keep the SessionHandle
private to the network layer and use only SessionId
elsewhere.
2011-09-13
Let's Code Dimdwarf #66: State Machine DSL
The code in ClientSessions has started to resemble a domain specific language for state machines with its operations, transitions and actions. Let's refactor it towards a DSL. After recording this episode I refactored it still some more off-camera. See these three last commits for the final DSL.
2011-09-05
Let's Code Dimdwarf #65: Feature Complete
The state machine has now been implemented and most logic has been moved from the controller to the ClientSessions state machine, leaving the controller focused on just simple mapping. Only some refactoring remains.
2011-08-21
Let's Code Dimdwarf #64: Asynchronous State Machine
When a collaborator can work both synchronously and asynchronously, it complicates things as the caller needs to make less assumptions. In our unit tests the authenticator is a synchronous fake (it keeps the tests simpler), but the production authenticator is asynchronous (because it does blocking operations). The state machine needs to be updated to work with both synchronous and asynchronous collaborators.
2011-08-14
Let's Code Dimdwarf #63: You Will Be Assimilated
The ClientSessions class will absorb most of the logic from NetworkController, leaving the controller just wiring things together and delegating all work to others. Let's first move the authentication logic.
2011-08-06
Let's Code Dimdwarf #62: Refactoring Domino
It's curious how sometimes with TDD the refactoring steps follow each other almost automatically, like dominoes. You make one small change and then just keep on fixing test failures until it all works again and the refactoring is done.
2011-07-24
Let's Code Dimdwarf #61: State Machine
The code starts to be ripe enough to be refactored into a state machine.
2011-07-17
Let's Code Dimdwarf #60: Smells Like State Machine
As disconnecting sessions comes to play, the code starts to inhibit code smells - conditional logic. It would be possible to get rid of those smells with a state machine and the state pattern, but the smells are still quite faint, so let's implement still one more step before refactoring, so that it will be obvious that what shape the code should take.
2011-07-06
Let's Code Dimdwarf #59: Session ID Mapping
When you would like to expose some internal state of a class just to be able to write tests for it, it's usually better to extract that internal thing into its own class which can then be tested through its public interface. Thus I will start writing a new class for keeping track of the mapping between sessions and session IDs.
2011-06-15
Let's Code Dimdwarf #58: Session IDs
Once we have timestamps, generating session IDs is trivial (but anyways worth writing a test for). Then the real thing is mapping those IDs to sessions, which is far from trivial.
2011-06-09
Let's Code Dimdwarf #57: Thread-Safe Clock
The factory for generating unique timestamps must be thread-safe. So I will write a test for thread-safeness and start using an AtomicReference.
2011-06-02
2011-05-29
Let's Code Dimdwarf #55: Pretty Printing
It's always good to be extra careful when dealing with the maximum and minimum values of an integer. After solving that bug in the tests, I'll improve the toString method.
2011-05-19
Let's Code Dimdwarf #54: Timestamp Ordering
To be able to implement session IDs, guaranteed unique values will be needed - also in a clustered environment. That can be solved by creating unique timestamps based on the paper Time, Clocks, and the Ordering of Events in a Distributed System (though first I'll implement simpler timestamps). I'll start by implementing the ordering of the timestamps, for which parameterized tests are useful.
2011-05-14
Let's Code Dimdwarf #53: Fixing Encapsulation
I will start deepening and widening the design by first fixing the encapsulation issue with the network layer - the NetworkActor
's private message queue should only be accessed by the NetworkController
.
2011-05-12
Let's Code Dimdwarf #52: Progressive Deepening
In this episode I get the session message roundtrip working with the simplest possible implementation - all in one method, without any layering. Of course this cannot work in production, but it lets us get started with something that works. After that it's time to do progressive deepening - introduce more layers into the software and push the functionality to the layer where it belongs to - and also do progressive widening - flesh out those layers with more functionality and production-ready quality (see Craftsmanship and Ethics at 18-21 min).
2011-05-08
Let's Code Dimdwarf #51: Walking Skeleton
My strategy for implementing session messages - and the half a dozen still nonexistent components which it depends on - is to start with a walking skeleton. This is the approach recommended in the GOOS book which I wrote about in Design for Integrability. In this episode I will explain my strategy and implement the outline of the walking skeleton.
Actually this is the second time during this project that I've used a walking skeleton. The first walking skeleton included receiving a login request and responding to it with a login failure. The first skeleton let me put in place these components: system startup, application loading, networking, authentication and the controller-actor architecture. This second skeleton will produce: unique timestamps, session IDs, worker thread handling, application APIs to listen for and send session messages, executing tasks in application code, sending session messages and committing transactions.
P.S. I wonder whether these may technically be called the first and second walking skeleton, since they don't include all main architectural components. This system has lots of essential complexity, so I prefer taking as small steps as possible. You could say that at first I implemented the legs of the walking skeleton (the controller-actor achitecture), now I implement the hands of the walking skeleton (task execution), and later I will implement the head of the walking skeleton (persistence).