Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add netstring encode/decode/stream library #1808

Merged
merged 2 commits into from
Sep 20, 2020
Merged

Conversation

warner
Copy link
Member

@warner warner commented Sep 19, 2020

For use by the kernel-worker protocol.

refs #1797
closes #1807

This is not yet complete: I still need tests for the streaming interfaces, which I'm not entirely sure how to write.

@kriskowal could you eyeball the implementation and maybe see if I'm on the right track? Any ideas about how I should go about the test?

@warner warner added the SwingSet package: SwingSet label Sep 19, 2020
@warner warner self-assigned this Sep 19, 2020
@kriskowal
Copy link
Member

For TChannel, we used a bounded search test to suss out boundary conditions in the framing protocol. This should be easier. https://github.com/uber/tchannel-node/blob/master/test/streaming_bisect.js

assert.equal(encoding, 'buffer');
buffered = Buffer.concat([buffered, chunk]);
let res = null;
try {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Node.js deoptimizes any function contain try/catch. This can be addressed by layering any function that contains try/catch such that it’s isolated in a very small inner frame.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does that mean minimizing the number of variables closed over by the function containing the try/catch?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, minimizing the closure isn’t necessary.

eq('abc', '3:abc,');
const umlaut = 'ümlaut';
t.is(umlaut.length, 6);
const umlautBuffer = Buffer.from(umlaut, 'utf-8');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ve been leaning harder on web API’s to make these kinds of libraries easier to port. To that end, Uint8Array, TextDecoder, and TextEncoder are handy, albeit less convenient than Buffer.from.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would also increase portability to frame this API in terms of async iterators and relieve the dependence on Node.js-specific streams. Node.js streams do implement async iterators so bridging should not be hard.

packages/SwingSet/test/test-netstring.js Outdated Show resolved Hide resolved
}

// Input is a Buffer containing zero or more netstrings and maybe some
// leftover bytes. Output is zero or more decoded Buffers, one per netstring,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be clearer if s/decoded buffers/strings.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but I don't think they are strings, right? they're strictly Buffer objects, if I understand correctly

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, you are right. I was confused by the symmetry and “decoded”. Would “extracted” be a better term? Decode implied bytes in, string out to me.

For use by the kernel-worker protocol.

refs #1797
closes #1807
@warner warner marked this pull request as ready for review September 19, 2020 22:55
@warner
Copy link
Member Author

warner commented Sep 19, 2020

Ok, I got the code all working, and expanded the tests (and also squashed, sorry). Ready for proper review now.

I'm uncertain about the Buffer/string distinction; I agree that using U8IntArray would be more general, but it sounds like it might be slightly harder to use, and our use case is somewhat narrow (two functions, both under our control, both in a Node.js -based start-compartment). I'll follow your judgement, do you think I should change it from what it looks like now?

}

// Input is a Buffer containing zero or more netstrings and maybe some
// leftover bytes. Output is zero or more decoded Buffers, one per netstring,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, you are right. I was confused by the symmetry and “decoded”. Would “extracted” be a better term? Decode implied bytes in, string out to me.

assert.equal(encoding, 'buffer');
buffered = Buffer.concat([buffered, chunk]);
let res = null;
try {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, minimizing the closure isn’t necessary.

@kriskowal
Copy link
Member

No further changes necessary for portability or performance in this first cut.

@warner warner merged commit e3c969b into master Sep 20, 2020
@warner warner deleted the 1807-netstring branch September 20, 2020 06:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
SwingSet package: SwingSet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

add netstring+Stream utility
2 participants