Overview

As shown above, a typical pub/sub system has a server who maintains a
collection of topics, which serve as endpoints for messages. Clients
connect to this server and perform the following operations:

IDENTIFY: This identifies and authenticates the client to the server.

PUBLISH: This posts a message to a particular topic queue.

SUBSCRIBE: This notifies the server that a client is interested in a
particular topic.

RETRIEVE: This fetches all the messages destined for the client.

DISCONNECT: This notifies the server that the client is disconnecting.

In the diagram, Client A connects to the Server and first performs
an IDENTIFY command with its name and nonce or key. It then publishes
a message to the TOPIC_A endpoint and then disconnects.

Client B, on the other hand, also performs an IDENTIFY operation and
the proceeds to SUBSCRIBE to TOPIC_A and then RETRIEVE any messages
for it. If Client B had subscribed to TOPIC_A before Client A
published its message, then Client B would receive the message during
this RETRIEVE operation.

Working in groups of one or two people, you are to create a
library that utilizes POSIX threads and concurrent data structures
to implement a client for the described pub/sub system by midnight on
Tuesday, October 10, 2017. Additionally, you are to utilize this
library to build and demonstrate a distributed and parallel application of
your choosing by Thursday, October 26, 2017.

More details about this project and your deliverables are described below.

Clients must IDENTIFY before performing any other operations.
Otherwise the result of any unauthorized operations will be: "401 Not
identified yet.

Clients should maintain a connection to the server and send and receive
messages on this one connection.

When a client disconnects, the server removes any subscriptions and
messages associated with that client.

Furthermore, in this pub/sub system, the server will handle as many
clients as system resources allow and will continuously process requests
until the client disconnects (implicitly or explicitly).

Client Library

The main goal of this project is to create a client library (ie.
lib/libps_client.a) that communicates to a pub/sub server as described
above. This library will be used by a variety of test programs and an user
application.

Application Programming Interface (API)

The client library must implement a Client class with the following
methods:

This constructs a Client object with the specified server host,
server port, and client identify cid.

Client::Client(constchar*host, constchar*port, constchar*cid)

This schedules a message with the specified topic, message, and
length to be published to the server.

Finally, the library must provide a Thread class with the following
methods:

This starts the thread with the specified func and arg.

void Thread::start(thread_func func, void*arg);

This joins the thread and stores the return value in the result.

void Thread::join(void**result);

This detaches the thread so it can run without needing to be joined.

void Thread::detach();

Concurrency

The client library should utilize multiple POSIX threads to enable
concurrent publishing and retrieving messages. This means that at any
one time, the library should be able to do the following things
concurrently:

Publishing: The library should be able to publish any messages that
have been queued up.

Retrieving: The library should be able to retrieve any messages that
the server has available to the client.

Callbacks: The library should able to process any retrieved messages
by passing the retrieved message to any matching callback handlers.

To further test your client library, you will need to implement unit
tests using the Google Test framework as described below.

User Application

Once you have implemented the client library and are confident in your
testing, you must create a distributed and parallel application that
utilizes the pub/sub system. Here are some possible applications:

The exact user application is up to you. However, the application must
utilize your client library and must utilize multiple threads correctly.

Deliverables

As noted above, you are to work in groups of one or two (three
is permitted, but discouraged) to implement pq. You must use C++ as
the implementation language. Any test scripts or auxillary tools can be
written in any reasonable scripting language.

You will need to modify this Makefile to support your user application.

K.I.S.S.

While the exact organization of the project code is up to you, keep in mind
that you will be graded in part on coding style, cleaniness, and
organization. This means your code should be consistently formatted, not
contain any dead code, have reasonable comments, and appropriate naming
among other things:

Break long functions into smaller functions.

Make sure each function does one thing and does it well.

Abstract, but don't over do it.

Please refer to these Coding Style slides for some tips and guidelines on
coding style expectations.

Demonstration

As part of your grade, you will need to present your user
application to a TA where you will demonstrate the correctness of
your pub/sub client library and the implementation of your user
application.

Testing

While creating your user application, you should be creating tests in
the form of functional tests (ie. bin/echo_test) and unit tests (ie.
bin/client_unit).

The point of these tests is to ensure your application works correctly and
to allow you to catch any possible bugs in your code. For instance, you
may wish to test any concurrent data structures you created or to check how
your client library handles message parsing and communication.

Ideally, each method or function you write would have a corresponding unit
test or is covered by a functional test application.

To help with testing, we have included the Google Test framework in the
Project 03 repository and have include some stubs you can expand to write
your unit tests.

For this project, you must have both functional and unit tests and
utilize them regularly during your application development process.

Test-Driven Development

Writing all the tests at the end of your development process defeats the
purpose of the test-driven development. What you should do is try to
implement one feature or function at a time and test it as you
build it. Rather than trying to implement multiple pieces all at once,
focus on one thing at a time and incrementally build your application.

Presentation

As part of your demonstration, you must provide a presentation (between 5
- 10 slides) with the following content:

Design: An overview of the design of your user application.

Implementation: A summary of how you implemented the user
application and utilized the pub/sub system.

Testing: A discussion on how you tested your client library and your
end user application.

Paradigms: A discussion on how you used three different concurrency
programming paradigms: message passing, threading, and events and what the
challenge of each model is.

Summary: A summary of what you learned.

Note, you should incorporate images, graphs, diagrams and other visual
elements as part of your presentation where reasonable.

Please upload these slides to Google Drive and place a link in your
README.md.

Be prepared to be asked about different aspects of your project, as the TA
may ask you questions to probe your understanding of the material and your
work.

Documentation

As noted above, the Project 03 repository includes a README.md file
with the following sections:

Members: This should be a list of the project members.

Design: This is a list of design questions that you should answer
before you do any coding as they will guide you towards the resources
you need.

Demonstration: This is where you should provide a Google Drive
link to your demonstration slides.

Errata: This is a section where you can describe any deficiencies or
known problems with your implementation.

You must complete this document report as part of your project.

Design and Implementation

You should look at the design questions in the README.md file of the
Project 03 repository. The questions there will help you design and plan
your process queue implementation.

Feel free to ask the TAs or the instructor for some guidance on these
questions before attempting to implement this project.

Extra credit

Once you have completed your project, you may extend your implementation of
libps_client by performing either (or both) of the following
modifications:

Graphical User Interface: Create a graphical application using a
toolkit such as Qt that utilizes your libps_client.

Scripting Interface: Create a language binding to your
libps_client so that you can utilize the library from a scripting
language such as [Python] or [Ruby] to replicate the echo_test program.