Project 2: Tiny Bookstore Project
Checkout project by Wednesday, October 4
Preliminary Deadline: Monday, October 16 - (at
least) completed synchronized server-side code, with (basic) client
implementation, preliminary testing of system. Code should be pushed
to GitHub. Tag this version
with preliminary_implementation
Final
Deadline: Tuesday, October 24 - evaluation scripts, graphing,
write up, testing, fixing any issues uncovered by continued work.
This project has two goals:
- to help you gain experience with remote procedure calls, from the perspective of the client and the server.
- to teach you about the design and internals of a multi-tier distributed system
This project should be done in teams of two.
Part 0: Set Up
- Follow the link to the GitHub classroom assignment
- Follow the directions for cloning the repository, adapting the directions as appropriate for this project. Return to this page for importing the project.
- To import the project, you'll go into
the
Working Tree
under the cloned repository. Right-click on tinybookstore and choose to import the project. (If you see more than one project, choose the project that saysMaven
under the "Import As" column,tinybookstore
directory, to import.) - The project is a Maven project, which allows us to easily get dependencies, like the Apache XMLRPC jar files. Right-click on the project, go to Maven, and click "Update Project", if you're getting compiler errors.
- You should see
Maven Dependencies
in the Package Explorer view. When you expand the dependencies, you should see the xmlrpc-server, xmlrpc-client, and other jar files, e.g.,
Part 1: Build the Store
You have been tasked to design TinyBookstore.com - the World's smallest online bookstore. TinyBookstore.com carries only four books:
- Achieving Less Bugs with More Hugs in CSCI 325 (item: 53477)
- Distributed Systems for Dummies (item: 53573)
- Surviving College (item: 12365)
- Cooking for the Impatient Undergraduate (item: 12498)
Since TinyBookstore.com hopes to one day become the next Amazon, they would like to use sound design principles to design their online store in order to allow for future growth.
The store will employ a two-tier design: a front-end and a back-end. The front-end tier will accept user requests and perform initial processing. The backend consists of two components: a catalog server and an order server. The catalog server maintains the catalog (which currently consists of the above four entries). For each entry, it maintains the number of items in stock, cost of the book (you can pick the price), and the topic of the book. Currently all books belong to one of two topics: distributed systems (first two books) and college life (the last two books). The order server maintains a list of all orders received for the books.
The front end server supports three operations:
search(topic)
- given a topic (or category), returns all entries belonging to that category (a title and an item number are displayed for each match).lookup(item_number)
- given an item number, returns details such as title, number of items in stock, and cost for each match.buy(item_number)
- specifies an item number for purchase (assume the desired quantity is always 1).
The first two operations trigger queries on the catalog server. The buy operation triggers a request to the order server.
The catalog server supports two operations: query
and update
. Two types of queries are supported:
query-by-subject and query-by-item. In the first case, a topic
is specified and the server returns all matching entries. In the
second case, an item number is specified and all relevant details are
returned. The update operation allows the cost of an item to be
updated or the number of items in stock to be increased or
decreased. You can implement update as either one or two procedures.
The order server supports a single
operation: buy(item_number)
. Upon receiving a buy
request, the order server must first verify that the item is in
stock by querying the catalog server and then decrement the
number of items in stock by one. (Note: what could happen
if you would try to implement the previous statement as two
separate function calls?) The buy request can fail if the
item is out of stock. Assume that new stock arrives
periodically (you can pick the interval--easier to add more
inventory and increase the interval) and the catalog is updated
accordingly.
The client program should allow users to test all functionality in the order they desire.
A pictorial representation of the system is as shown in the figure below.
Other requirements:
- Each component should use XML-RPC.
- Each [server] component should be able to accept multiple
requests at the same time.
Be aware of the thread synchronizing issues to avoid inconsistency or deadlock in your system. For instance, a order server should be able to process multiple concurrent buy requests and decrementing the number of items in stock should be done using synchronization. You may find the Javasynchronized
primitive helpful here. - You should implement your servers in Java and your clients in Python.
- The servers should take as command-line arguments the hostname and the port number that the server is running on. (You can have the server use defaults if command-line arguments are not provided.)
- The client should take as command-line arguments the front-end server's hostname and port number (again, you can allow defaults).
No GUIs are required. Simple text-based interfaces are fine.
Testing
Hopefully, you followed good design principles and built the system up incrementally.
How can you test the system to make sure that your system is properly synchronized? Do your best to put your system into the worst-case scenario.
Part 2: Evaluation
It's time for the all-important evaluation of your system. Design experiments and scripts to do the following:
- Compute the average response time per
client
search
request by measuring the response time seen by a client for 500 sequential requests. - Compute the average response time per
buy
request for 500 sequential requests. - Rerun experiments 1) and 2) with multiple clients concurrently making requests to the system. Does your average response time change as the number of concurrent requests changes?
Suggestions/Hints
- Python has modules/functions for getting the current time.
- Limit the number of unnecessary application running while you're running experiments. Why?
- Run experiments multiple times. Why?
- Using Threads in Python
Part 3: Write up
After implementing TinyBookstore.com, write a document that describes your system. You should describe the data structures you used and how you synchronized. Include any assumptions that you made (e.g., about the restock), along with any problems that you were unable to solve. Discuss how you tested. Finally, you should describe your experimental setup and graphs to support your answers to the evaluation questions.
Part 4: Submission
GitHub Classroom will make a snapshot of your repository at the deadline. Your repository should contain:
- Your writeup (as a PDF).
- All the files for your source code
- A copy of the output generated by running your program. When a client purchases a book, have your program print a message "bought book book_name". When a client issues a query (lookup/search), have your program print the returned results in a nicely formatted manner.
Resources
I have collected some resources to help you get started with various aspects of this assignment:
- XML-RPC Official Home Page
- Apache XML-RPC for Java, Javadocs
- XML-RPC for Python
- XML-RPC Implementations, if you're curious
Graphing for Evaluation
- Matplotlib - create graphs using Python
Maybe Helpful Hints
- RPC method calls can't return anything "out of the ordinary", i.e., no home-grown data structures. They can only return "the basics" that all programming languages/XML will understand.
- All RPC methods must return _something_. They cannot be void.