Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18c54885f4 | ||
|
|
644e5e4a4d | ||
|
|
ca17e686f2 | ||
|
|
a2ed298d34 | ||
|
|
8509161f7c | ||
|
|
b88ab5a305 | ||
|
|
ac4c2574a6 | ||
|
|
0ba69aec95 | ||
|
|
7ef8da3d79 | ||
|
|
0e9376071e | ||
|
|
d75642d0e8 | ||
|
|
6eb94df293 | ||
|
|
544bf09271 | ||
|
|
b45f75c8f9 | ||
|
|
752d3cdffd | ||
|
|
0371c68bcd | ||
|
|
ae6f591602 | ||
|
|
81aeebf181 | ||
|
|
0cc5054ea2 | ||
|
|
cdda439e4a | ||
|
|
932e589f36 | ||
|
|
46fd0a8b6e | ||
|
|
5e8c4c0b1b | ||
|
|
7ab91af445 | ||
|
|
05644ec31b | ||
|
|
28de5052c0 | ||
|
|
c720781a5f | ||
|
|
d8de1b49ad | ||
|
|
4df200effa | ||
|
|
cbb3ab40fb | ||
|
|
eae9c1c54b | ||
|
|
1abd120c12 | ||
|
|
ca30a96c1c | ||
|
|
d2f4c72d64 | ||
|
|
202e13c66f | ||
|
|
a3e975d43c | ||
|
|
f1e9306cd6 | ||
|
|
c6fe3c2624 | ||
|
|
7fb9018515 | ||
|
|
742d6b5b79 | ||
|
|
ec1721f298 | ||
|
|
5aeffa328a |
No files matched your search
@@ -22,7 +22,7 @@ messages from complete Javascript objects. This actually makes the library
|
||||
somewhat nicer syntactically than it would be otherwise, but it is not fast.
|
||||
|
||||
A pure-Javascript implementation would likely be much faster. See
|
||||
[capnp-js](https://github.com/capnp-js/serialization) for such an
|
||||
[capnp-js](https://github.com/capnp-js) for such an
|
||||
implementation. Unfortunately, that implementation is incomplete and does not
|
||||
support [RPC](https://github.com/capnp-js/rpc) just yet. Hence, this hack was
|
||||
created for short-term use.
|
||||
@@ -47,11 +47,11 @@ you must have development headers for Cap'n Proto and Node.js installed, along
|
||||
with the `node-gyp` tool and a GCC new enough for Cap'n Proto (at least 4.7).
|
||||
On Debian/Ubuntu, you can install these like so:
|
||||
|
||||
sudo apt-get install nodejs-dev nodejs-legacy capnproto-dev g++
|
||||
sudo apt-get install nodejs-dev nodejs-legacy libcapnp-dev g++
|
||||
|
||||
### Form source
|
||||
### From source
|
||||
|
||||
git clone git://github.com/kenton/node-capnp.git
|
||||
git clone git://github.com/capnproto/node-capnp.git
|
||||
cd node-capnp
|
||||
npm install
|
||||
|
||||
@@ -118,6 +118,25 @@ we copied.)
|
||||
// object containing the results by name.
|
||||
promise.then(function(response) {
|
||||
console.log(response.namedResult);
|
||||
})
|
||||
// If the remote object throws an rpc exception, the promise will be
|
||||
// rejected. The error returned will have a property `kjType`, which
|
||||
// will be a string representation of the exception's `type` field.
|
||||
.catch(function(error) {
|
||||
switch(error.kjType) {
|
||||
case 'failed':
|
||||
console.log("A generic problem occurred:", error.message);
|
||||
break;
|
||||
case 'overloaded':
|
||||
console.log("Resource overload on the remote end:", error.message);
|
||||
break;
|
||||
case 'disconnected':
|
||||
// ...
|
||||
break;
|
||||
case 'unimplemented':
|
||||
// ...
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
### Pipelining
|
||||
@@ -196,6 +215,22 @@ then use that:
|
||||
In this case, the library only wraps `myFoo` as a capability once, and then
|
||||
calls `close()` once all copies of that reference have been dropped.
|
||||
|
||||
If one of your methods throws an exception, or returns a promise which
|
||||
is subsequently rejected, it will be converted to a capnproto rpc
|
||||
exception. If the exception has a `kjType` property, that will be used
|
||||
for the exception's `type` field, otherwise the type will be `failed`.
|
||||
|
||||
var myBar = {
|
||||
bar: function(foo) {
|
||||
if(!bazAvailable()) {
|
||||
var err = new Error("The baz is busy; try again later.");
|
||||
err.kjType = 'overloaded';
|
||||
throw(err);
|
||||
}
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
### Exporting a bootstrap capability
|
||||
|
||||
// Connect to another server and export `myFoo` as a bootstrap capability.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
capnp.node
|
||||
+2
-2
@@ -4,12 +4,12 @@
|
||||
'target_name': 'capnp',
|
||||
'sources': ['src/node-capnp/capnp.cc'],
|
||||
'libraries': ['-lkj', '-lkj-async', '-lcapnp', '-lcapnpc', '-lcapnp-rpc'],
|
||||
'cflags_cc': ['-std=c++11'],
|
||||
'cflags_cc': ['-std=c++14'],
|
||||
'cflags_cc!': ['-fno-rtti', '-fno-exceptions'],
|
||||
'conditions': [
|
||||
[ 'OS=="mac"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS' : ['-std=c++11','-stdlib=libc++'],
|
||||
'OTHER_CPLUSPLUSFLAGS' : ['-std=c++14','-stdlib=libc++'],
|
||||
'OTHER_LDFLAGS': ['-stdlib=libc++'],
|
||||
'GCC_ENABLE_CPP_RTTI': 'YES',
|
||||
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
|
||||
|
||||
@@ -72,10 +72,13 @@ if (!force) {
|
||||
|
||||
// Build it
|
||||
function build() {
|
||||
cp.spawn(
|
||||
var sp = cp.spawn(
|
||||
process.platform === 'win32' ? 'node-gyp.cmd' : 'node-gyp',
|
||||
['rebuild'].concat(args),
|
||||
{customFds: [0, 1, 2]})
|
||||
{customFds: [0, 1, 2]});
|
||||
|
||||
sp
|
||||
.on('close', function(){ afterBuild(); })
|
||||
.on('exit', function(err) {
|
||||
if (err) {
|
||||
if (err === 127) {
|
||||
@@ -88,8 +91,9 @@ function build() {
|
||||
}
|
||||
return process.exit(err);
|
||||
}
|
||||
afterBuild();
|
||||
});
|
||||
sp.stdout.pipe(process.stdout);
|
||||
sp.stderr.pipe(process.stderr);
|
||||
}
|
||||
|
||||
// Move it to expected location
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require("capnp").importSystem("capnp/c++.capnp");
|
||||
+7
-4
@@ -1,8 +1,11 @@
|
||||
{
|
||||
"name": "capnp",
|
||||
"version": "0.2.0",
|
||||
"version": "0.5.0",
|
||||
"description": "A wrapper for the C++ Cap'n Proto library",
|
||||
"keywords": [ "capnproto", "serialization" ],
|
||||
"keywords": [
|
||||
"capnproto",
|
||||
"serialization"
|
||||
],
|
||||
"homepage": "http://capnproto.org",
|
||||
"author": {
|
||||
"name": "Kenton Varda",
|
||||
@@ -15,8 +18,8 @@
|
||||
"email": "jparyani@gmail.com"
|
||||
}
|
||||
],
|
||||
|
||||
"main": "src/node-capnp/capnp.js",
|
||||
"types": "src/node-capnp/capnp.d.ts",
|
||||
"scripts": {
|
||||
"install": "node ./build.js",
|
||||
"test": "node src/node-capnp/capnp-test.js"
|
||||
@@ -26,7 +29,7 @@
|
||||
"url": "git://github.com/kentonv/node-capnp.git"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
"node": ">=10.0"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require("capnp").importSystem("capnp/persistent.capnp");
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require("capnp").importSystem("capnp/rpc-twoparty.capnp");
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require("capnp").importSystem("capnp/rpc.capnp");
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require("capnp").importSystem("capnp/schema.capnp");
|
||||
@@ -263,31 +263,48 @@ child.stdio[1].once("readable", function() {
|
||||
closed: false
|
||||
};
|
||||
|
||||
var localCap = new capnp.Capability(pow, Calculator.Function);
|
||||
assert.equal(9, wait(localCap.call([3, 2])).value);
|
||||
assert(!pow.closed);
|
||||
localCap.close();
|
||||
assert(pow.closed);
|
||||
function usePow(pow) {
|
||||
var localCap = new capnp.Capability(pow, Calculator.Function);
|
||||
assert.equal(9, wait(localCap.call([3, 2])).value);
|
||||
assert(!pow.closed);
|
||||
localCap.close();
|
||||
assert(pow.closed);
|
||||
|
||||
var promise = calc.evaluate(
|
||||
{call: {"function": subtract, params: [
|
||||
{call: {"function": add, params: [
|
||||
{literal: 123}, {literal: 456}]}},
|
||||
{literal: 321}]}});
|
||||
var promise = calc.evaluate(
|
||||
{call: {"function": subtract, params: [
|
||||
{call: {"function": add, params: [
|
||||
{literal: 123}, {literal: 456}]}},
|
||||
{literal: 321}]}});
|
||||
|
||||
var value = promise.value;
|
||||
assert.equal(258, wait(value.read()).value);
|
||||
value.close();
|
||||
var value = promise.value;
|
||||
assert.equal(258, wait(value.read()).value);
|
||||
value.close();
|
||||
|
||||
pow.closed = false;
|
||||
value = calc.evaluate(
|
||||
{call: {"function": pow, params: [{literal: 2}, {literal: 4}]}}).value;
|
||||
assert.equal(16, wait(value.read()).value);
|
||||
pow.closed = false;
|
||||
value = calc.evaluate(
|
||||
{call: {"function": pow, params: [{literal: 2}, {literal: 4}]}}).value;
|
||||
assert.equal(16, wait(value.read()).value);
|
||||
|
||||
// Wait a moment to give the capability a chance to be dropped.
|
||||
wait(new Promise((resolve, reject) => setTimeout(resolve, 10)));
|
||||
assert(pow.closed);
|
||||
value.close();
|
||||
// Wait a moment to give the capability a chance to be dropped.
|
||||
wait(new Promise((resolve, reject) => setTimeout(resolve, 10)));
|
||||
assert(pow.closed);
|
||||
value.close();
|
||||
}
|
||||
usePow(pow);
|
||||
|
||||
// Try using a class.
|
||||
class PowClass {
|
||||
constructor() {
|
||||
this.closed = false
|
||||
}
|
||||
call(params) {
|
||||
return Math.pow(params[0], params[1]);
|
||||
}
|
||||
close() {
|
||||
this.closed = true;
|
||||
}
|
||||
};
|
||||
usePow(new PowClass());
|
||||
|
||||
// Try wrapping a promise as a capability -- calls are queued until resolution.
|
||||
var resolvePromisedCalc;
|
||||
|
||||
+361
-247
File diff suppressed because it is too large.
Load diff
Vendored
+45
@@ -0,0 +1,45 @@
|
||||
declare module Capnp {
|
||||
type Id = string;
|
||||
|
||||
abstract class StructSchema<Builder, Reader> {
|
||||
// A schema for a struct type. The `Builder` parameter is what users of
|
||||
// the library specify in order to create a value; it may be missing fields,
|
||||
// which will be filled in with defaults. A `Reader` is what is is returned
|
||||
// when parsing a value, and is guaranteed to have all known fields set.
|
||||
|
||||
typeId: Id;
|
||||
}
|
||||
|
||||
abstract class InterfaceSchema<Server, Client> {
|
||||
// A schema for an interface type. Similarly to `StructSchema`, the `Server`
|
||||
// and `Client` parameters represent objects which may have missing
|
||||
// methods (for servers), and ones which do not (for clients, though calling
|
||||
// the method may still throw unimplemented).
|
||||
|
||||
typeId: Id;
|
||||
}
|
||||
|
||||
interface AnyServer {
|
||||
close?: () => void;
|
||||
}
|
||||
|
||||
interface AnyClient {
|
||||
close(): void;
|
||||
closed: boolean;
|
||||
castAs<Server, Client>(schema: InterfaceSchema<Server, Client>): Client;
|
||||
}
|
||||
|
||||
const Capability: {
|
||||
new<Server, Client>(server: Server, schema: InterfaceSchema<Server, Client>): Client;
|
||||
}
|
||||
|
||||
abstract class Connection {
|
||||
restore<Server, Client>(exportName: string, type: InterfaceSchema<Server, Client>): Client;
|
||||
close(): void;
|
||||
}
|
||||
|
||||
function parse<Builder, Reader>(type: StructSchema<Builder, Reader>, buffer: Buffer): Reader;
|
||||
function serialize<Builder, Reader>(type: StructSchema<Builder, Reader>, builder: Builder): Buffer;
|
||||
function connect(addr: string): Connection;
|
||||
}
|
||||
export default Capnp;
|
||||
+13
-11
@@ -192,16 +192,20 @@ function wrapLocalMethod(self, method) {
|
||||
}
|
||||
|
||||
function LocalCapWrapper(obj) {
|
||||
for (var name in obj) {
|
||||
if (name === "close") {
|
||||
// Not an RPC method. Called when the capability has no clients.
|
||||
this.close = obj.close.bind(obj);
|
||||
} else {
|
||||
var method = obj[name];
|
||||
if (typeof method === "function") {
|
||||
this[name] = wrapLocalMethod(obj, method);
|
||||
var type = obj;
|
||||
while (type && type !== Object.prototype) {
|
||||
Object.getOwnPropertyNames(type).forEach(name => {
|
||||
if (name === "close") {
|
||||
// Not an RPC method. Called when the capability has no clients.
|
||||
this.close = obj.close.bind(obj);
|
||||
} else {
|
||||
var method = obj[name];
|
||||
if (typeof method === "function") {
|
||||
this[name] = wrapLocalMethod(obj, method);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
type = Object.getPrototypeOf(type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,5 +302,3 @@ exports.bytesToPreorder = function(schema, buf, options) {
|
||||
|
||||
if (v8capnp.matchPowerboxQuery) exports.matchPowerboxQuery = v8capnp.matchPowerboxQuery;
|
||||
if (v8capnp.chacha20) exports.chacha20 = v8capnp.chacha20;
|
||||
|
||||
exports.dumpLocalCapTypeCounts = v8capnp.dumpLocalCapTypeCounts;
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require("capnp").importSystem("capnp/stream.capnp");
|
||||
Reference in new issue
Block a user