Wendy Chen
CPSC 426 Distributed Systems, Fall 2016
The following service description is adapted from the lab specification:
Service description
The first iteration of the graph store is a simple single-node in-memory service. A server hosts the graph and handles client requests to modify or query the graph. The graph is erased from memory when the server stops.
The user should be able to invoke the graph server by specifying the port in the command line: ./cs426_graph_server <port>
The service expects simple HTTP requests with a Content-Length header, and arguments specified in JSON. Requests should be in the form:
HTTP/1.1 <status_code> <status_message>
Content-Length: <length>
Content-Type: application/json
{
<JSON_arguments>
}
All requests will be POST requests. The following functions can be handled by the graph server:
Function | Arguments | Return |
---|---|---|
add_node | u64 node_id | 200 on success 204 if the node already exists |
add_edge | u64 node_a_id, u64 node_b_id | 200 on success 204 if the edge already exists 400 if either node doesn't exist, or if node_a_id is the same as node_b_id |
remove_node | u64 node_id | 200 on success 400 if the node does not exist |
remove_edge | u64 node_a_id, u64 node_b_id | 200 on success 400 if the edge does not exist |
get_node | u64 node_id | 200 and a boolean JSON field in_graph indicating whether the node is in the graph |
get_edge | u64 node_a_id, u64 node_b_id | 200 and a boolean JSON field in_graph indicating whether the edge is in the graph 400 of at least one of the vertices does not exist |
get_neighbors | u64 node_id | 200 and a list of neighbors or 400 if the node does not exist |
shortest_path | u64 node_a_id, u64 node_b_id | u64 and a field distance containing the length of shortest path between the two nodes or 204 if there is no path 400 if either node does not exist |
Compilation Details
The current Makefile is for MacOSX. The functions needed from Mongoose are included in mongoose.c, so no installation is required.
Implementation Details
The implementation is split into three areas: the graph, the server, and the http request handling. These three areas are handled by the following files, respectively: graph.cpp, cs426_graph_server.cpp, and api.cpp.
The Graph class is defined in graph.h. As requested by the specification, all graph mutation and query functions are defined as class methods in graph.cpp. When the graph service is running, an instance of the Graph class is constructed, and this instance is not preserved when the service terminates.
The server is set up in cs426_graph_server.cpp. Mongoose is used for setting up the server, and parsing JSON attached to http requests. When the server is running, it listens at the specified port for incoming events. Each defined event corresponds to one of the functions from the lab specification. When handling an event, the server calls a function from api.cpp.
The functions from api.cpp are wrappers for calling Graph methods in addition to emitting an http response. Mongoose is used for emitting JSON.
Test script and Examples
The test script I have provided (test.sh) builds a simple graph of six nodes and calls all the allowed functions. Besides using the test script, http requests can also be sent using curl:
curl -H "Content-Type: application/json" -X POST -d '{"node_id":1}' http://127.0.0.1:8000/api/v1/add_node
Links:
Home: Demo video and Abstract
First iteration: Local in-memory graph
Second iteration: Durable on-disk graph
Third iteration: Chain-replicated graph
Fourth iteration: Partitioned graph
Source code: Each graph is stored under its appropriate branch (lab1, lab2, lab3, lab4)