Iteration 10: Distribution using Broker II


Always at 23.59 on the same day as your TA session (Except Monday classes).

Consult the deadline for your class on the delivery plan.

Learning Goals

The primary learning goal of this iteration is to implement object reference handling in the Broker architecture, and secondary to integrate and (potentially) refactor the Invoker code for all types in HotCiv.

The project goal is to have a fully distributed HotCiv system with the GUI integrated.


Solve and document exercises:

  1. Broker 2.1. TDD of Game methods that Transfer Server Objects. Implement the remaining Game methods that return object references (getUnitAt(), getCityAt(), etc.) using TDD and test doubles.
  2. Broker 2.2. Integrate type invokers and implement Multi Type Dispatching. Remove the 'objectId fakeit code' from the City, Tile, and Unit invokers developed in the previous exercise, and integrate it into a full Multi Type Dispatcher system.
  3. Broker 2.3. System test. Develop and manually system test/demonstrate that two socket based hotciv clients (target: 'hotcivClient'), connected to the hotciv server (target: 'hotcivServer'), each presenting the user with the MiniDraw based GUI can execute properly as a distributed system. Your system test should validate that the two players can:

And release them using the tag/branch name "Release10".


  1. Document your group's work by following the requirements defined in the iteration 10 report template (pdf) (LaTeX source)
  2. Create one approximately 4-8 minutes long screencasts with audio narration, which demonstrates starting your HotCiv server, then start two graphical clients, and perform/explain the system tests outlined in exercise Broker 2.3.

Optional Exploration Exercises

Chatty and Chunky interfaces

As mentioned, the HotCiv Game interface was never constructed with distribution in mind. As one evident example, consider the GUI redrawing the units: It will do so by iterating in a double for loop over all rows and all columns, and for each (row, column) invoke the game.getUnitAt(position) method.

Thus, for every GUI redraw, you have (at least) 256 remote method calls!

This is an example of a performance engineering anti pattern: Chatty interface. That is, an interface that forces a lot of network chatter.

Software architecture knowledge dictates that architects need to consider distribution early and avoid designing chatty interfaces between remote roles. The pattern to use is Chuncky interface, that is creating interfaces that bulk transfer a lot of information in single network package.

We are actually helped a lot here, because we have our own Broker implementation! Nobody tells us to implement every ClientProxy method as a real Proxy method, and indeed a nifty way is to use client side caching.

So - here is the exercise:

Implement caching in the ClientProxy's getUnitAt(Position p) method, that expires after N seconds.

That is, you keep an internal data structure in the ClientProxy that stores all UnitClientProxy objects. The first ever call to getUnitAt() will notice that this data structure is empty and then make a single Chunky call to the server and retrieve ALL information on ALL units in the game. All subsequent calls will return objects stored in the cache (the internal data structure) instead of calling the server, unless the current time is more than N seconds since the last chunky server call. If more than N seconds have elapsed, the cache has expired, and you fetch from the server again.

Setting N to 1 or 2 seconds will ensure that the every GUI redraw only makes a single server call. The only liability is that the redraw may be incorrect in the (unlikely) event that a state change is made in during that 1-2 second that the cache is valid.

Note that you will have to recode both the ClientProxy method as well as the Invoker handling.

Polling Observer

  1. Make a server side game observer that keeps log of state events with a incrementing sequence number (index in array may suffice)
  2. Make a client side observer that periodically poll the server to fetch a list of all state events since the last fetched event like getEventsSinceEventWithID(47) or something like that.
  3. Make the client replay any events, in case it receives some.

Disclaimer: I have not implemented the above idea, so I am not certain that you do not run into unforseen issues...

Notes and Hints

I strongly advice to have a good look at the code base of the GameLobby system as well as the corresponding explanation in the "Flexible, Reliable, Distributed System" book.

And, review the notes and hints in the W12-5 Mandatory Hints slides.

Evaluation criteria

Your submission is evaluated against the learning goals and adherence to the submission guidelines. The grading is explained in Grading Guidelines. The TAs will use the Iteration 10 Grade sheet to evaluate your submission. The score counts towards your final grade.

Learning Goal Assessment parameters
Submission Git repository can be pulled using "Release10". Git repository is not public! Code must compile; 'gradle test jacocoTestReport' must pass, and so must the system test targets; required artefact (report following the template, screencast video of good quality) is present.
Transferring Server Objects The implementations of the transferring of server objects from server to client is functionally correct (allow clients to correctly interact with associated server object through their ClientProxies), implement a suitable name service for object lookup at the server side, and the code is clean. The report document process and resulting code correctly.
Multi Type Dispatching The implementations of multi type dispatching is functionally correct, sub invokers are cohesively and correctly associated with specific types, and the code is clean. The report document process and resulting code correctly.
System Testing The system test correctly runs a distributed SemiCiv.
Functional complete The HotCiv mandatory project is functionally complete, i.e., all mandatory requirements are implemented correctly. (No need to implement optional or non-required exercises, like EtaCiv).