From 1d369e5f80361c45a262e5febf169ea8d32af977 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 19 Feb 2015 10:28:41 -0800 Subject: Added comments and fixed some minor bugs --- src/node/examples/route_guide_server.js | 77 ++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 2 deletions(-) (limited to 'src/node/examples/route_guide_server.js') 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(); -- cgit v1.2.3