Skip to content

Commit

Permalink
pbjs static target services support
Browse files Browse the repository at this point in the history
  • Loading branch information
dcodeIO committed Dec 3, 2016
1 parent 98d6ae1 commit 81e36a7
Show file tree
Hide file tree
Showing 11 changed files with 466 additions and 58 deletions.
83 changes: 47 additions & 36 deletions bench/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,46 +23,57 @@ protobuf.load(require.resolve("./bench.proto"), function onload(err, root) {
var Test = root.lookup("Test");

protobuf.util.codegen.verbose = true;
var buf = Test.encode(data).finish(),
dec = Test.decode(buf);

var str = JSON.stringify(data),
strbuf = Buffer.from(str, "utf8");
var buf = Test.encode(data).finish();

newSuite("encoding")
.add("Type.encode to buffer", function() {
// warm up
for (var i = 0; i < 500000; ++i)
Test.encode(data).finish();
})
.add("JSON.stringify to string", function() {
JSON.stringify(data);
})
.add("JSON.stringify to buffer", function() {
new Buffer(JSON.stringify(data), "utf8");
})
.run();

newSuite("decoding")
.add("Type.decode from buffer", function() {
for (var i = 0; i < 1000000; ++i)
Test.decode(buf);
})
.add("JSON.parse from string", function() {
JSON.parse(str);
})
.add("JSON.parse from buffer", function() {
JSON.parse(strbuf.toString("utf8"));
})
.run();
console.log("");

// give the optimizer some time to do its job
setTimeout(function() {
var str = JSON.stringify(data),
strbuf = Buffer.from(str, "utf8");

newSuite("encoding")
.add("Type.encode to buffer", function() {
Test.encode(data).finish();
})
.add("JSON.stringify to string", function() {
JSON.stringify(data);
})
.add("JSON.stringify to buffer", function() {
new Buffer(JSON.stringify(data), "utf8");
})
.run();

newSuite("decoding")
.add("Type.decode from buffer", function() {
Test.decode(buf);
})
.add("JSON.parse from string", function() {
JSON.parse(str);
})
.add("JSON.parse from buffer", function() {
JSON.parse(strbuf.toString("utf8"));
})
.run();

newSuite("combined")
.add("Type to/from buffer", function() {
Test.decode(Test.encode(data).finish());
})
.add("JSON to/from string", function() {
JSON.parse(JSON.stringify(data));
})
.add("JSON to/from buffer", function() {
JSON.parse(new Buffer(JSON.stringify(data), "utf8").toString("utf8"));
})
.run();

newSuite("combined")
.add("Type to/from buffer", function() {
Test.decode(Test.encode(data).finish());
})
.add("JSON to/from string", function() {
JSON.parse(JSON.stringify(data));
})
.add("JSON to/from buffer", function() {
JSON.parse(new Buffer(JSON.stringify(data), "utf8").toString("utf8"));
})
.run();
}, 3000);

});
84 changes: 81 additions & 3 deletions cli/targets/static.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ module.exports = static_target;
// - You can specify a custom wrapper with the --wrap argument.
// - CommonJS modules depend on the minimal static runtime for reduced package size with browserify.
// - AMD and global scope depend on the full library for now.
// - Services aren't supported, yet.

var path = require("path"),
fs = require("fs");
Expand Down Expand Up @@ -230,9 +229,88 @@ function buildType(ref, type) {
}

function buildService(ref, service) {
var fullName = service.fullName.substring(1);

push("");
push(name(ref) + "." + name(service.name) + " = {};");
// TODO: Services are just empty objects currently
pushComment([
"Constructs a new " + service.name + ".",
"@exports " + fullName,
"@constructor",
"@param {function(function, Uint8Array, function)} rpc RPC implementation",
"@param {boolean} [requestDelimited=false] Whether requests are length-delimited",
"@param {boolean} [responseDelimited=false] Whether responses are length-delimited"
]);
push("function " + name(service.name) + "(rpc, requestDelimited, responseDelimited) {");
++indent;
push("");
pushComment([
"RPC implementation.",
"@type {function(function, Uint8Array, function)}"
]);
push("this.rpc = rpc;");
push("");
pushComment([
"Whether requests are length-delimited.",
"@type {boolean}"
]);
push("this.requestDelimited = Boolean(requestDelimited);");
push("");
pushComment([
"Whether responses are length-delimited.",
"@type {boolean}"
]);
push("this.responseDelimited = Boolean(responseDelimited);");
--indent;
push("};");
service.getMethodsArray().forEach(function(method) {
method.resolve();
var lcName = method.name.substring(0, 1).toLowerCase() + method.name.substring(1);
push("");
pushComment([
"Calls " + method.name + ".",
"@param {" + method.resolvedRequestType.fullName.substring(1) + "|Object} request " + method.resolvedRequestType.name + " or plain object",
"@param {function(?Error, " + method.resolvedResponseType.fullName.substring(1) + "=)} callback Node-style callback called with the error, if any, and " + method.resolvedResponseType.name,
"@returns {undefined}"
]);
push(name(service.name) + ".prototype." + name(lcName) + " = function " + name(lcName) + "(request, callback) {");
++indent;
push("var requestData;");
push("try {");
++indent;
push("requestData = (this.requestDelimited && $root" + name(method.resolvedRequestType.fullName) + ".encodeDelimited(request) || $root" + name(method.resolvedRequestType.fullName) + ".encode(request)).finish();");
--indent;
push("} catch (err) {");
++indent;
push("(typeof setImmediate === 'function' && setImmediate || setTimeout)(function() { callback(err); });");
push("return;");
--indent;
push("}");
push("var self = this;");
push("this.rpc(" + name(lcName) + ", requestData, function(err, responseData) {");
++indent;
push("if (err) {");
++indent;
push("callback(err);");
push("return;");
--indent;
push("}");
push("var response;");
push("try {");
++indent;
push("response = self.responseDelimited && $root" + name(method.resolvedResponseType.fullName) + ".decodeDelimited(responseData) || $root" + name(method.resolvedResponseType.fullName) + ".decode(responseData);");
--indent;
push("} catch (err2) {");
++indent;
push("callback(err2);");
push("return;");
--indent;
push("}");
push("callback(null, response);");
--indent;
push("});");
--indent;
push("};");
});
}

function buildEnum(ref, enm) {
Expand Down
13 changes: 7 additions & 6 deletions dist/protobuf.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/protobuf.js.map

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions dist/protobuf.min.js

Large diffs are not rendered by default.

Binary file modified dist/protobuf.min.js.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion dist/protobuf.min.js.map

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions src/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ ServicePrototype.remove = function remove(object) {
/**
* Creates a runtime service using the specified rpc implementation.
* @param {function(Method, Uint8Array, function)} rpc RPC implementation ({@link RPCImpl|see})
* @param {boolean} [requestDelimited=false] Whether request data is length delimited
* @param {boolean} [responseDelimited=false] Whether response data is length delimited
* @param {boolean} [requestDelimited=false] Whether requests are length-delimited
* @param {boolean} [responseDelimited=false] Whether responses are length-delimited
* @returns {Object} Runtime service
*/
ServicePrototype.create = function create(rpc, requestDelimited, responseDelimited) {
Expand All @@ -162,7 +162,8 @@ ServicePrototype.create = function create(rpc, requestDelimited, responseDelimit
value: rpc
});
this.getMethodsArray().forEach(function(method) {
rpcService[method.name] = function(request, callback) {
var lcName = method.name.substring(0, 1).toLowerCase() + method.name.substring(1);
rpcService[lcName] = function(request, callback) {
method.resolve();
var requestData;
try {
Expand Down
4 changes: 2 additions & 2 deletions src/writer.js
Original file line number Diff line number Diff line change
Expand Up @@ -546,8 +546,8 @@ BufferWriterPrototype.string = function write_string_buffer(value) {
? byteLength(value)
: util.Buffer.byteLength(value);
return len
? this.uint32(len).push(writeStringBuffer, len, value)
: this.push(writeByte, 1, 0);
? this.uint32(len).push(writeStringBuffer, len, value)
: this.push(writeByte, 1, 0);
};

/**
Expand Down
Loading

0 comments on commit 81e36a7

Please sign in to comment.