aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/node/examples/route_guide_server.js
diff options
context:
space:
mode:
authorGravatar murgatroid99 <mlumish@google.com>2015-02-19 10:28:41 -0800
committerGravatar murgatroid99 <mlumish@google.com>2015-02-19 10:28:41 -0800
commit1d369e5f80361c45a262e5febf169ea8d32af977 (patch)
tree5ae0df512873c57b869657b150e7648a7753f393 /src/node/examples/route_guide_server.js
parent2fdfaac92ed0433d98e7590f618d54f1e3c48861 (diff)
Added comments and fixed some minor bugs
Diffstat (limited to 'src/node/examples/route_guide_server.js')
-rw-r--r--src/node/examples/route_guide_server.js77
1 files changed, 75 insertions, 2 deletions
diff --git a/src/node/examples/route_guide_server.js b/src/node/examples/route_guide_server.js
index 3df90e9173..b21190d62e 100644
--- a/src/node/examples/route_guide_server.js
+++ b/src/node/examples/route_guide_server.js
@@ -35,19 +35,42 @@ var Server = grpc.buildServer([examples.RouteGuide.service]);
var COORD_FACTOR = 1e7;
+/**
+ * For simplicity, a point is a record type that looks like
+ * {latitude: number, longitude: number}, and a feature is a record type that
+ * looks like {name: string, location: point}. feature objects with name==='' are
+ * points with no feature.
+ */
+
+/**
+ * List of feature objects at points that have been requested so far.
+ */
var feature_list = [];
+/**
+ * Return a random "word" (alphabetic character sequence) of the given length.
+ * @param {number} length The length of the word to create
+ * @return {string} An alphabetic string with the given length.
+ */
function randomWord(length) {
var alphabet = 'abcdefghijklmnopqrstuvwxyz';
var word = '';
for (var i = 0; i < length; i++) {
+ // Add a random character from the alphabet to the word
word += alphabet[_.random(0, alphabet.length - 1)];
}
return word;
}
+/**
+ * Get a feature object at the given point, or creates one if it does not exist.
+ * @param {point} point The point to check
+ * @return {feature} The feature object at the point. Note that an empty name
+ * indicates no feature
+ */
function checkFeature(point) {
var feature;
+ // Check if there is already a feature object for the given point
for (var i = 0; i < feature_list.length; i++) {
feature = feature_list[i];
if (feature.point.latitude === point.latitude &&
@@ -55,6 +78,7 @@ function checkFeature(point) {
return feature;
}
}
+ // If not, create a new one with 50% chance of indicating "no feature present"
var name;
if (_.random(0,1) === 0) {
name = '';
@@ -65,14 +89,27 @@ function checkFeature(point) {
name: name,
location: point
};
+ // Add the feature object to the list and return it
feature_list.push(feature);
return feature;
}
+/**
+ * getFeature request handler. Gets a request with a point, and responds with a
+ * feature object indicating whether there is a feature at that point.
+ * @param {EventEmitter} call Call object for the handler to process
+ * @param {function(Error, feature)} callback Response callback
+ */
function getFeature(call, callback) {
callback(null, checkFeature(call.request));
}
+/**
+ * listFeatures request handler. Gets a request with two points, and responds
+ * with a stream of all features in the bounding box defined by those points.
+ * @param {Writable} call Writable stream for responses with an additional
+ * request property for the request value.
+ */
function listFeatures(call) {
var lo = call.request.lo;
var hi = call.request.hi;
@@ -80,7 +117,11 @@ function listFeatures(call) {
var right = _.max(lo.longitude, hi.longitude);
var top = _.max(lo.latitude, hi.latitude);
var bottom = _.max(lo.latitude, hi.latitude);
+ // For each feature, check if it is in the given bounding box
_.each(feature_list, function(feature) {
+ if (feature.name === '') {
+ return;
+ }
if (feature.location.longitude >= left &&
feature.location.longitude <= right &&
feature.location.latitude >= bottom &&
@@ -117,17 +158,28 @@ function getDistance(start, end) {
return R * c;
}
+/**
+ * recordRoute handler. Gets a stream of points, and responds with statistics
+ * about the "trip": number of points, number of known features visited, total
+ * distance traveled, and total time spent.
+ * @param {Readable} call The request point stream.
+ * @param {function(Error, routeSummary)} callback The callback to pass the
+ * response to
+ */
function recordRoute(call, callback) {
var point_count = 0;
var feature_count = 0;
var distance = 0;
var previous = null;
+ // Start a timer
var start_time = process.hrtime();
call.on('data', function(point) {
point_count += 1;
- if (checkFeature(point) !== '') {
+ if (checkFeature(point).name !== '') {
feature_count += 1;
}
+ /* For each point after the first, add the incremental distance from the
+ * previous point to the total distance value */
if (previous != null) {
distance += getDistance(previous, point);
}
@@ -137,7 +189,9 @@ function recordRoute(call, callback) {
callback(null, {
point_count: point_count,
feature_count: feature_count,
+ // Cast the distance to an integer
distance: distance|0,
+ // End the timer
elapsed_time: process.hrtime(start_time)[0]
});
});
@@ -145,13 +199,25 @@ function recordRoute(call, callback) {
var route_notes = {};
+/**
+ * Turn the point into a dictionary key.
+ * @param {point} point The point to use
+ * @return {string} The key for an object
+ */
function pointKey(point) {
return point.latitude + ' ' + point.longitude;
}
-function routeChat(call, callback) {
+/**
+ * routeChat handler. Receives a stream of message/location pairs, and responds
+ * with a stream of all previous messages at each of those locations.
+ * @param {Duplex} call The stream for incoming and outgoing messages
+ */
+function routeChat(call) {
call.on('data', function(note) {
var key = pointKey(note.location);
+ /* For each note sent, respond with all previous notes that correspond to
+ * the same point */
if (route_notes.hasOwnProperty(key)) {
_.each(route_notes[key], function(note) {
call.write(note);
@@ -159,6 +225,7 @@ function routeChat(call, callback) {
} else {
route_notes[key] = [];
}
+ // Then add the new note to the list
route_notes[key].push(note);
});
call.on('end', function() {
@@ -166,6 +233,11 @@ function routeChat(call, callback) {
});
}
+/**
+ * Get a new server with the handler functions in this file bound to the methods
+ * it serves.
+ * @return {Server} The new server object
+ */
function getServer() {
return new Server({
'examples.RouteGuide' : {
@@ -178,6 +250,7 @@ function getServer() {
}
if (require.main === module) {
+ // If this is run as a script, start a server on an unused port
var routeServer = getServer();
routeServer.bind('0.0.0.0:0');
routeServer.listen();