There’s Too Many Arguments!
Recently I added dynamic parameters to CruiseControl.Net. This caused a large number of method signatures to change – in multiple classes. After the project lead saw these changes, he mentioned that we’re probably not using the best approach for passing arguments, especially as in future we could potentially add more arguments!
At the same time this offers some possibilities for future-proofing. While we can’t move to WCF (at least for a while yet), we can set things up so a move to WCF is easy.
Some Messaging Approaches
Before I implement messaging, the question arises as to what is the best way to do it? There are a number of different models for messaging, so I’m going to quickly look at three.
One Way Messaging

In this model messages are sent from the client to the server. Nothing comes back from the server at all.
While this is nice and simple, there is no way of checking that the server has received the message and that the message is valid. It’s kind of like dropping a message into a black hole and hoping that it works.
This is how CruiseControl.Net Remoting works in many ways. When a force/abort build, start/stop project or other similar request is sent, it is assumed that they will work. As part of the security changes I turned on exception reporting, but this is using .Net Remoting instead of a reply from the server.
Two Way Messaging

This is similar to one-way messaging, except the server also sends back a response. Depending on the action, this response could be immediate or it could take a long time.
Most of the information requests to CruiseControl.Net use this model (e.g. get snapshot, get projects statuses, etc.) The server gets the request, processes it immediately and sends back the response.
Asynchronous Two Way Messaging

In this model the request and response are decoupled. Instead an acknowledgement is returned (ack for short) letting the message sender know that the message has been received. When the server receives the message it sends an ack and then processes the request. Finally, once the request has been completed it sends the response (optionally waiting for an ack that the client received it).
CruiseControl.Net doesn’t use this model at all, although the project build queuing does provide part of the model (the only part missing is the response at the end). While I foresee this as being very useful for clients in the future, I’m not going to attempt this (basically because of its complexity.)
Additional Models
These are three of the common messaging models – there are many other patterns also (I haven’t covered routing, composition, transactions, reliability, etc.) As this are the simple models I’m going to leave it here and instead move onto how we can use them in CruiseControl.Net.
Aiming For Consistency
With this background I can now begin to look at adding messaging. But first, some goals:
- Consistency – every message should have the same common elements, and every message should use the same model
- No exceptions – errors should be part of a message, rather than being outside of messaging
- Decoupling – the client should not be forced to wait on the server
The first two are readily achievable – the final goal will have to wait until I look at a common communications library.
For consistency, I want to move every message to a two-way model. This means that even the current one-way messages (e.g. force/abort build, start/stop project, etc.) will return a response to the client. In most scenarios this means the server will send a “success” response (e.g. I have received your force build request and added it to the queue), but it also allows for sending errors back to the client.
Currently an error is returned using an exception, which is a security hole (it allows external parties to see the structure of the code and potentially helps them to hack in). With the new model, errors will be returned as part of the response, allowing us much greater control over what is actually sent.
Next, I want to split the messages into two parts – a body and a header. The header contains information about the request that doesn’t directly apply to the message. At the moment I’m thinking about adding a project identifier, the session token and a message identifier.
The project identifier is a unique way of identifying every project. This identifier must be globally unique since the dashboard can handle multiple servers. As such this identifier will consist of the server name plus the the project name. If the request is a server-level request, then just the server name is required.
While this may seem like some duplicate of data (e.g. the server name is part of both the protocol and the message) it allows for consistency, plus provides some avenues for message validation later.
The session token is new to security. It allows a client to tell the server who is using it. Currently it is only used for active requests (e.g. force/abort build, start/stop project, etc.) plus security requests (e.g. change password, list users, etc.) I think this would also be useful for every request – both for consistency, plus for the future options it allows.
And finally, a message identifier. This would be a unique identifier for each message. While there is no requirement for it at the moment I foresee it being useful in security (for preventing message-repeat attacks). Ideally this should be combined with a timestamp to narrow the window of attack.
Laying the Foundation
Since this post is mainly about my plans for messaging, I’m not going to include any coding. Instead I’ll finish off with my design for the messages. Now this isn’t the full design, instead it’s an example of how the classes will be built:

The base class that every request needs to inherit from is ServerRequest. This contains the common “header” data for every request. Additionally, methods that need no further information can use this request directly.
Requests that inherit from this just add the additional properties that they require. For example, ProjectRequest just adds the project name. Any methods that just needs the project name (e.g. start/stop project) could then use this request.
More specialised requests can then inherit from these classes depending on what base information they need (e.g. ChangePasswordRequest inherits from ServerRequest while ForceBuildRequest and SendMessageRequest inherit from ProjectRequest).
Each request must be serialisable so it can be passed via .Net Remoting. Additionally I’m thinking of marking them up with XML serialisation attributes to help with HTTP requests.
Responses are very similar:

This is very similar – one root class (Response) plus some specialised classes.
The basic idea with these is to use any existing class if possible, otherwise add a new class to provide the custom request/response.
What About the Future?
With these request/response classes it should be fairly easy to port them to WCF. Just add the data contract attributes and then write a contract interface, plus implementation.
So this approach should also handle the move to WCF.
That’s a Wrap
So, that’s my intentions for messaging. Next I’ll have a go at implementing them and see how things work out.