Merge github.com:grpc/grpc into bye-bye-completion-queue-pie

This commit is contained in:
Craig Tiller 2015-05-12 14:08:56 -07:00
commit 05e692dac4
14 changed files with 154 additions and 87 deletions

View File

@ -33,25 +33,25 @@ syntax = "proto3";
package math;
message DivArgs {
optional int64 dividend = 1;
optional int64 divisor = 2;
int64 dividend = 1;
int64 divisor = 2;
}
message DivReply {
optional int64 quotient = 1;
optional int64 remainder = 2;
int64 quotient = 1;
int64 remainder = 2;
}
message FibArgs {
optional int64 limit = 1;
int64 limit = 1;
}
message Num {
optional int64 num = 1;
int64 num = 1;
}
message FibReply {
optional int64 count = 1;
int64 count = 1;
}
service Math {

View File

@ -66,18 +66,18 @@ service RouteGuide {
// Latitudes should be in the range +/- 90 degrees and longitude should be in
// the range +/- 180 degrees (inclusive).
message Point {
optional int32 latitude = 1;
optional int32 longitude = 2;
int32 latitude = 1;
int32 longitude = 2;
}
// A latitude-longitude rectangle, represented as two diagonally opposite
// points "lo" and "hi".
message Rectangle {
// One corner of the rectangle.
optional Point lo = 1;
Point lo = 1;
// The other corner of the rectangle.
optional Point hi = 2;
Point hi = 2;
}
// A feature names something at a given point.
@ -85,19 +85,19 @@ message Rectangle {
// If a feature could not be named, the name is empty.
message Feature {
// The name of the feature.
optional string name = 1;
string name = 1;
// The point where the feature is detected.
optional Point location = 2;
Point location = 2;
}
// A RouteNote is a message sent while at a given point.
message RouteNote {
// The location from which the message is sent.
optional Point location = 1;
Point location = 1;
// The message to be sent.
optional string message = 2;
string message = 2;
}
// A RouteSummary is received in response to a RecordRoute rpc.
@ -107,14 +107,14 @@ message RouteNote {
// the distance between each point.
message RouteSummary {
// The number of points received.
optional int32 point_count = 1;
int32 point_count = 1;
// The number of known features passed while traversing the route.
optional int32 feature_count = 2;
int32 feature_count = 2;
// The distance covered in metres.
optional int32 distance = 3;
int32 distance = 3;
// The duration of the traversal in seconds.
optional int32 elapsed_time = 4;
int32 elapsed_time = 4;
}

View File

@ -33,13 +33,13 @@ package examples;
// Protocol type definitions
message StockRequest {
optional string symbol = 1;
optional int32 num_trades_to_watch = 2 [default=0];
string symbol = 1;
int32 num_trades_to_watch = 2;
}
message StockReply {
optional float price = 1;
optional string symbol = 2;
float price = 1;
string symbol = 2;
}

View File

@ -161,7 +161,7 @@ NAN_METHOD(Server::New) {
grpc_server *wrapped_server;
grpc_completion_queue *queue = CompletionQueueAsyncWorker::GetQueue();
if (args[0]->IsUndefined()) {
wrapped_server = grpc_server_create(queue, NULL);
wrapped_server = grpc_server_create(NULL);
} else if (args[0]->IsObject()) {
Handle<Object> args_hash(args[0]->ToObject());
Handle<Array> keys(args_hash->GetOwnPropertyNames());
@ -190,11 +190,12 @@ NAN_METHOD(Server::New) {
return NanThrowTypeError("Arg values must be strings");
}
}
wrapped_server = grpc_server_create(queue, &channel_args);
wrapped_server = grpc_server_create(&channel_args);
free(channel_args.args);
} else {
return NanThrowTypeError("Server expects an object");
}
grpc_server_register_completion_queue(wrapped_server, queue);
Server *server = new Server(wrapped_server);
server->Wrap(args.This());
NanReturnValue(args.This());
@ -212,6 +213,7 @@ NAN_METHOD(Server::RequestCall) {
grpc_call_error error = grpc_server_request_call(
server->wrapped_server, &op->call, &op->details, &op->request_metadata,
CompletionQueueAsyncWorker::GetQueue(),
CompletionQueueAsyncWorker::GetQueue(),
new struct tag(new NanCallback(args[0].As<Function>()), ops.release(),
shared_ptr<Resources>(nullptr)));
if (error != GRPC_CALL_OK) {

View File

@ -28,7 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
syntax = "proto3";
package grpc.testing;

View File

@ -86,7 +86,7 @@ function emptyUnary(client, done) {
*/
function largeUnary(client, done) {
var arg = {
response_type: testProto.PayloadType.COMPRESSABLE,
response_type: 'COMPRESSABLE',
response_size: 314159,
payload: {
body: zeroBuffer(271828)
@ -94,9 +94,8 @@ function largeUnary(client, done) {
};
var call = client.unaryCall(arg, function(err, resp) {
assert.ifError(err);
assert.strictEqual(resp.payload.type, testProto.PayloadType.COMPRESSABLE);
assert.strictEqual(resp.payload.body.limit - resp.payload.body.offset,
314159);
assert.strictEqual(resp.payload.type, 'COMPRESSABLE');
assert.strictEqual(resp.payload.body.length, 314159);
});
call.on('status', function(status) {
assert.strictEqual(status.code, grpc.status.OK);
@ -138,7 +137,7 @@ function clientStreaming(client, done) {
*/
function serverStreaming(client, done) {
var arg = {
response_type: testProto.PayloadType.COMPRESSABLE,
response_type: 'COMPRESSABLE',
response_parameters: [
{size: 31415},
{size: 9},
@ -150,8 +149,8 @@ function serverStreaming(client, done) {
var resp_index = 0;
call.on('data', function(value) {
assert(resp_index < 4);
assert.strictEqual(value.payload.type, testProto.PayloadType.COMPRESSABLE);
assert.strictEqual(value.payload.body.limit - value.payload.body.offset,
assert.strictEqual(value.payload.type, 'COMPRESSABLE');
assert.strictEqual(value.payload.body.length,
arg.response_parameters[resp_index].size);
resp_index += 1;
});
@ -182,23 +181,21 @@ function pingPong(client, done) {
});
var index = 0;
call.write({
response_type: testProto.PayloadType.COMPRESSABLE,
response_type: 'COMPRESSABLE',
response_parameters: [
{size: response_sizes[index]}
],
payload: {body: zeroBuffer(payload_sizes[index])}
});
call.on('data', function(response) {
assert.strictEqual(response.payload.type,
testProto.PayloadType.COMPRESSABLE);
assert.equal(response.payload.body.limit - response.payload.body.offset,
response_sizes[index]);
assert.strictEqual(response.payload.type, 'COMPRESSABLE');
assert.equal(response.payload.body.length, response_sizes[index]);
index += 1;
if (index === 4) {
call.end();
} else {
call.write({
response_type: testProto.PayloadType.COMPRESSABLE,
response_type: 'COMPRESSABLE',
response_parameters: [
{size: response_sizes[index]}
],
@ -251,7 +248,7 @@ function cancelAfterBegin(client, done) {
function cancelAfterFirstResponse(client, done) {
var call = client.fullDuplexCall();
call.write({
response_type: testProto.PayloadType.COMPRESSABLE,
response_type: 'COMPRESSABLE',
response_parameters: [
{size: 31415}
],
@ -270,18 +267,19 @@ function cancelAfterFirstResponse(client, done) {
* Run one of the authentication tests.
* @param {string} expected_user The expected username in the response
* @param {Client} client The client to test against
* @param {?string} scope The scope to apply to the credentials
* @param {function} done Callback to call when the test is completed. Included
* primarily for use with mocha
*/
function authTest(expected_user, client, done) {
function authTest(expected_user, client, scope, done) {
(new GoogleAuth()).getApplicationDefault(function(err, credential) {
assert.ifError(err);
if (credential.createScopedRequired()) {
credential = credential.createScoped(AUTH_SCOPE);
if (credential.createScopedRequired() && scope) {
credential = credential.createScoped(scope);
}
client.updateMetadata = grpc.getGoogleAuthDelegate(credential);
var arg = {
response_type: testProto.PayloadType.COMPRESSABLE,
response_type: 'COMPRESSABLE',
response_size: 314159,
payload: {
body: zeroBuffer(271828)
@ -291,9 +289,8 @@ function authTest(expected_user, client, done) {
};
var call = client.unaryCall(arg, function(err, resp) {
assert.ifError(err);
assert.strictEqual(resp.payload.type, testProto.PayloadType.COMPRESSABLE);
assert.strictEqual(resp.payload.body.limit - resp.payload.body.offset,
314159);
assert.strictEqual(resp.payload.type, 'COMPRESSABLE');
assert.strictEqual(resp.payload.body.length, 314159);
assert.strictEqual(resp.username, expected_user);
assert.strictEqual(resp.oauth_scope, AUTH_SCOPE_RESPONSE);
});
@ -318,8 +315,9 @@ var test_cases = {
empty_stream: emptyStream,
cancel_after_begin: cancelAfterBegin,
cancel_after_first_response: cancelAfterFirstResponse,
compute_engine_creds: _.partial(authTest, COMPUTE_ENGINE_USER),
service_account_creds: _.partial(authTest, AUTH_USER)
compute_engine_creds: _.partial(authTest, COMPUTE_ENGINE_USER, null),
service_account_creds: _.partial(authTest, AUTH_USER, AUTH_SCOPE),
jwt_token_creds: _.partial(authTest, AUTH_USER, null)
};
/**

View File

@ -72,10 +72,9 @@ function handleUnary(call, callback) {
var req = call.request;
var zeros = zeroBuffer(req.response_size);
var payload_type = req.response_type;
if (payload_type === testProto.PayloadType.RANDOM) {
payload_type = [
testProto.PayloadType.COMPRESSABLE,
testProto.PayloadType.UNCOMPRESSABLE][Math.random() < 0.5 ? 0 : 1];
if (payload_type === 'RANDOM') {
payload_type = ['COMPRESSABLE',
'UNCOMPRESSABLE'][Math.random() < 0.5 ? 0 : 1];
}
callback(null, {payload: {type: payload_type, body: zeros}});
}
@ -89,7 +88,7 @@ function handleUnary(call, callback) {
function handleStreamingInput(call, callback) {
var aggregate_size = 0;
call.on('data', function(value) {
aggregate_size += value.payload.body.limit - value.payload.body.offset;
aggregate_size += value.payload.body.length;
});
call.on('end', function() {
callback(null, {aggregated_payload_size: aggregate_size});
@ -103,10 +102,9 @@ function handleStreamingInput(call, callback) {
function handleStreamingOutput(call) {
var req = call.request;
var payload_type = req.response_type;
if (payload_type === testProto.PayloadType.RANDOM) {
payload_type = [
testProto.PayloadType.COMPRESSABLE,
testProto.PayloadType.UNCOMPRESSABLE][Math.random() < 0.5 ? 0 : 1];
if (payload_type === 'RANDOM') {
payload_type = ['COMPRESSABLE',
'UNCOMPRESSABLE'][Math.random() < 0.5 ? 0 : 1];
}
_.each(req.response_parameters, function(resp_param) {
call.write({
@ -127,10 +125,9 @@ function handleStreamingOutput(call) {
function handleFullDuplex(call) {
call.on('data', function(value) {
var payload_type = value.response_type;
if (payload_type === testProto.PayloadType.RANDOM) {
payload_type = [
testProto.PayloadType.COMPRESSABLE,
testProto.PayloadType.UNCOMPRESSABLE][Math.random() < 0.5 ? 0 : 1];
if (payload_type === 'RANDOM') {
payload_type = ['COMPRESSABLE',
'UNCOMPRESSABLE'][Math.random() < 0.5 ? 0 : 1];
}
_.each(value.response_parameters, function(resp_param) {
call.write({

View File

@ -30,7 +30,7 @@
// Message definitions to be used by integration test service definitions.
syntax = "proto2";
syntax = "proto3";
package grpc.testing;
@ -49,46 +49,46 @@ enum PayloadType {
// A block of data, to simply increase gRPC message size.
message Payload {
// The type of data in body.
optional PayloadType type = 1 [default = COMPRESSABLE];
PayloadType type = 1;
// Primary contents of payload.
optional bytes body = 2;
bytes body = 2;
}
// Unary request.
message SimpleRequest {
// Desired payload type in the response from the server.
// If response_type is RANDOM, server randomly chooses one from other formats.
optional PayloadType response_type = 1 [default = COMPRESSABLE];
PayloadType response_type = 1;
// Desired payload size in the response from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression.
optional int32 response_size = 2;
int32 response_size = 2;
// Optional input payload sent along with the request.
optional Payload payload = 3;
Payload payload = 3;
// Whether SimpleResponse should include username.
optional bool fill_username = 4;
bool fill_username = 4;
// Whether SimpleResponse should include OAuth scope.
optional bool fill_oauth_scope = 5;
bool fill_oauth_scope = 5;
}
// Unary response, as configured by the request.
message SimpleResponse {
// Payload to increase message size.
optional Payload payload = 1;
Payload payload = 1;
// The user the request came from, for verifying authentication was
// successful when the client expected it.
optional string username = 2;
string username = 2;
// OAuth scope.
optional string oauth_scope = 3;
string oauth_scope = 3;
}
// Client-streaming request.
message StreamingInputCallRequest {
// Optional input payload sent along with the request.
optional Payload payload = 1;
Payload payload = 1;
// Not expecting any payload from the response.
}
@ -96,18 +96,18 @@ message StreamingInputCallRequest {
// Client-streaming response.
message StreamingInputCallResponse {
// Aggregated size of payloads received from the client.
optional int32 aggregated_payload_size = 1;
int32 aggregated_payload_size = 1;
}
// Configuration for a particular response.
message ResponseParameters {
// Desired payload sizes in responses from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression.
optional int32 size = 1;
int32 size = 1;
// Desired interval between consecutive responses in the response stream in
// microseconds.
optional int32 interval_us = 2;
int32 interval_us = 2;
}
// Server-streaming request.
@ -116,17 +116,17 @@ message StreamingOutputCallRequest {
// If response_type is RANDOM, the payload from each response in the stream
// might be of different types. This is to simulate a mixed type of payload
// stream.
optional PayloadType response_type = 1 [default = COMPRESSABLE];
PayloadType response_type = 1;
// Configuration for each expected response message.
repeated ResponseParameters response_parameters = 2;
// Optional input payload sent along with the request.
optional Payload payload = 3;
Payload payload = 3;
}
// Server-streaming response, as configured by the request and parameters.
message StreamingOutputCallResponse {
// Payload to increase response size.
optional Payload payload = 1;
Payload payload = 1;
}

View File

@ -30,7 +30,8 @@
// An integration test service that covers all the method signature permutations
// of unary/streaming requests/responses.
syntax = "proto2";
syntax = "proto3";
import "empty.proto";
import "messages.proto";

View File

@ -1,6 +1,6 @@
{
"name": "grpc",
"version": "0.7.0",
"version": "0.8.0",
"author": "Google Inc.",
"description": "gRPC Library for Node",
"homepage": "http://www.grpc.io/",
@ -26,7 +26,7 @@
"dependencies": {
"bindings": "^1.2.0",
"nan": "^1.5.0",
"protobufjs": "^4.0.0-b2",
"protobufjs": "dcodeIO/ProtoBuf.js",
"underscore": "^1.6.0",
"underscore.string": "^3.0.0"
},

View File

@ -50,7 +50,7 @@ function deserializeCls(cls) {
* @return {cls} The resulting object
*/
return function deserialize(arg_buf) {
return cls.decode(arg_buf);
return cls.decode(arg_buf).toRaw();
};
}

39
test/echo_service.proto Normal file
View File

@ -0,0 +1,39 @@
// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
message EchoMessage {
string value = 1;
int32 value2 = 2;
}
service EchoService {
rpc Echo (EchoMessage) returns (EchoMessage);
}

View File

@ -99,6 +99,36 @@ describe('Surface server constructor', function() {
}, /math.Math/);
});
});
describe('Echo service', function() {
var server;
var client;
before(function() {
var test_proto = ProtoBuf.loadProtoFile(__dirname + '/echo_service.proto');
var echo_service = test_proto.lookup('EchoService');
var Server = grpc.buildServer([echo_service]);
server = new Server({
'EchoService': {
echo: function(call, callback) {
callback(null, call.request);
}
}
});
var port = server.bind('localhost:0');
var Client = surface_client.makeProtobufClientConstructor(echo_service);
client = new Client('localhost:' + port);
server.listen();
});
after(function() {
server.shutdown();
});
it('should echo the recieved message directly', function(done) {
client.echo({value: 'test value', value2: 3}, function(error, response) {
assert.ifError(error);
assert.deepEqual(response, {value: 'test value', value2: 3});
done();
});
});
});
describe('Generic client and server', function() {
function toString(val) {
return val.toString();

View File

@ -27,14 +27,14 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto2";
syntax = "proto3";
message Request {
optional bool error = 1;
bool error = 1;
}
message Response {
optional int32 count = 1;
int32 count = 1;
}
service TestService {