10 — Revised!
Due Wednesday, 30 November 2023, 11:59:59pm with an automatic extension until Sunday, 03 December, 11:59:59pm
Delivery Place the product of this week’s milestone into your git repo as follows:
for the Programming Task, modify the client, server, referee, and scoring functionality in your code and document the changes in configurations.md, which goes into Q/Planning/;
for the Runnable task, place xserver and xclients and Tests/ into a top-level repo directory named 10
Programming Task The co-CEOs received a request from their investors to make the software system configurable. Specifically, they would like the sample server, referee, and scoring functionality to be configurable for a number of properties. Specifically,
The server configuration specifies the port to listen to, for how many rounds the server waits, for how long each waiting period lasts, for how long it waits for a player’s name, and a referee configuration.
A referee configuration contains a state, the per-turn time for a calls to players, and optionally an observer.
A scoring configuration determines the bonus values for finishing a game or completing a Q during a turn.
Design and implement a data representation for configurations that can specify a fixed set of properties. Note that the configuration for one component may contain a configuration for another.
Abstract the server, the referee, and the scoring functionality over their respective configurations.
xserver, which starts your server from a JSON configuration, and
xclients, which launches a number of clients from a JSON configuration and points them to a server.
Both programs are launched with one command-line argument and a JSON object coming in from STDIN. The first specifies the port on which servers and clients connect; the configuration is an object with fields that approximately correspond to the requested internal configurations. The port fields in the configuration are populated with randomly chosen numbers; your scripts must use the PortNumber from the command line.
$ ./xserver PortNumber < FileNameForServerConfig & |
$ ./xclients PortNumber < FileNameForClientConfig & |
Keep in mind though that the JSON sent from clients to servers should not be trusted and for that matter clients may not wish to trust servers either.
The xclients script turns the player specifications into independently running players.
If players are launched without precaution, the test is going to run in a non-deterministic fashion and will yield non-deterministic – and therefore irreproducible – results. To reduce the likelihood of a non-deterministic outcome, the xclients script will wait for some number of seconds between launching clients. See below.
The xserver spawns the server program. The server waits for the players to sign up and passes their local representation plus the given referee configuration to the referee. The latter runs a game and hands the result of running the game back to the server, which renders it as a JSON value to STDOUT.
The test harness ensures that the server program runs independently of the client programs. You may to wish write xclients as a short TAHBPL program that spins up threads or as a shell (bash) script that spawns Linux processes. In either case, the idea is to spawn the server and the clients as parallel programs to mimic a distributed setting as much as possible using a single machine.
The test bed compares this actual output to the expected output of the test case; it ignores the output of xclients.
n-client-config.json, a client configuration;
n-server-config.json, a server configuration; and
n-out.json, the expected output
{ "port"___ : Natural (between 10000 and 60000), |
{ "host"___ : String (either an IP address or a domain name), |
{ "wait"___ : Natural (less than 10s), |
{ "quiet"__ : Boolean, |
{ "players" : JActorsB } |
INTERPRETATION The xclients script is expected to launch the specified |
players as independent threads or processes that communicate with the |
specified host on the given port, in the order listed. Between launches |
the script pauses for the number of seconds specified in the "wait" |
field. Recall that the value of the "port" field is irrelevant; the |
port number is specified on the command line. (The "quiet" exists |
for controlling any debug output the same purpose as the "quiet" fields mentioned above.) |
{ "port"___________ : Natural (between 10000 and 60000), |
{ "server-tries"___ : Natural (less than 10), |
{ "server-wait"____ : Natural (less than 30[s]), |
{ "wait-for-signup" : Natural (less than 10), |
{ "quiet"__________ : Boolean, |
{ "ref-spec"_______ : RefereeConfig } |
INTERPRETATION The xserver script listens on the specified port for the |
given number of waiting periods as described in 9 — |
sufficient number of players are signed up, it hands the referee the |
included configuration and the proxy players. Recall that the value of |
the "port" field is irrelevant; the port number is specified |
on the command line. |
{ "state0"__ : JState, |
{ "quiet"___ : Boolean, |
{ "config-s" : RefereeStateConfig, |
{ "per-turn" : Natural (less than or equal to 6), |
{ "observe"_ : Boolean } |
INTERPRETATION The xserver script will turn this JSON configuration object |
into the chosen internal data representation for referee configurations and |
include it with the server configuration. |
{ "qbo" : Natural (less or equal to 10), |
{ "fbo" : Natural (less or equal to 10) } |
INTERPRETATION The xserver script will turn this JSON configuration object |
into the chosen internal data representation for scoring configurations and |
include it with the referee configuration. |
String is "127.0.0.1" (and usually a sequence of ASCII chars). |
The state's players in the server configuration and the player specs in the client configuration match up just like in the preceding milestones.