8.3.0.10

10 — This is it!

Due Thursday, 02 December 2021, 11:59.59pm

Delivery Place the product of this week’s milestone into your repo as follows:

Programming Task It is time to complete phase 3 of our Trains.Com, a Plan. A complete distributed prototype will allow our angel investors to understand the complete idea. They can then provide feedback on how we can make this enterprise even more profitable.

Your software architect has derived a specification for the Remote Interactions from the Logical Interactions/2. The new specification includes a sign-up step.

Your task is to implement this server-client architecture. At this moment, your code base contains almost all the components needed for completing this task. When you touch complex software, you are likely to enbug it. So don’t touch the logical components if you can avoid it. The OOD patterns community teaches us that remote proxies are your friends here. They allow developers to inject a remote-communication layer into a software system while leaving the logical parts of a software system undisturbed.

The client TCP-connects a player (or several players) to a server.

The server waits for TCP connections sign-ups for some time (here, 20)s for a minimum number (here, 5) of remote clients to connect and sign up. As long as there isn’t this minimum number of clients connected and signed up at the end of a waiting period, the server re-enters the waiting state (just once) and for the same amount of time; the second time around it will run a tournament if only 2 sign up. Either waiting period also ends when the server has accepted a maximal number (here, 50) of client connections sign ups; this limit makes the duration of a tournament reasonable. If at most one player signs up by the end of the second waiting period, the server doesn’t run a tournament and instead delivers a simple default result:  [ [], [] ].

A server-client connection is established after the client has supplied the player’s name.

If a sufficient number of clients establish a connection, the server hands them to the manager. When the manager’s work is done, your server delivers the manager’s results as a JSON value to STDOUT.

Communication To make this exercise slightly realistic, each side of the server-client architecture must protect itself against ill-formed or invalid JSON messages from the other side. This is especially true for the server component, because a service should not collapse just because a client sends a bad message. The client-side component could in principle rely on the server-side component to send well-formed and valid JSON messages, but it’s better to be safe than sorry (think of the huge fee a client-creator pays to participate in Trains tournaments).

Misbehaving Players In a distributed setting, all bad client behavior turns into bad JSON messages or a lack of a response. Make sure to protect all the interactions (that is, remote calls and returns) between the server and clients by timing out connections after 2.0 seconds.

Runnables Task Construct two executable programs:
  • xserver, which starts your server, and

  • xclients, which launches a number of clients and points them to a server.

Both programs are launched with a port argument on the command line. For xclients, the command line may also specify an IP address, as an optional second argument; the default is local host (127.0.0.1).

Their inputs—both xserver and xclientsare the same as those for xref from 8 — The League (and the optional xmanager from 9 — Help!). The inputs have the same interpretation, though xserver uses only the colored cards part to configure the manager, while xclients uses the first two JSON values to create clients. Again, all client-players send the given map to the manager.

As with the tests, these configuration files are well-formed and valid JSON.

The output of xserver is either the JSON string "error: not enough destinations" or the outcome of running the tournament. The latter consists of a JSON array that contains two Ranks: the first contains the names of the winner(s) and the second contains the names of the misbehaving players. The test bed compares this actual output to the expected output of test cases.—The test bed waits for a generous 80s (+ (* 2 (~a [hash-ref DEFAULT-CONFIG SERVER-WAIT])) 40)s for the server to print this result, i.e., the span of two waiting periods plus 40s for running the tournament.

The test bed ignores the output of xclients.

Note You could write xclients as a shell script. If your language supports threads, you should write it in that language. In any case, you do want to spawn the clients as parallel programs to mimic a distributed setting as much as possible using a single machine.