Skip to content

L41: Asynchronous port binding method in Node Server API#108

Merged
murgatroid99 merged 4 commits intogrpc:masterfrom
murgatroid99:L41-node-async-bind
Oct 19, 2018
Merged

L41: Asynchronous port binding method in Node Server API#108
murgatroid99 merged 4 commits intogrpc:masterfrom
murgatroid99:L41-node-async-bind

Conversation

@murgatroid99
Copy link
Copy Markdown
Member

@murgatroid99 murgatroid99 commented Sep 28, 2018

Copy link
Copy Markdown

@cjihrig cjihrig left a comment

Choose a reason for hiding this comment

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

Makes sense to me. I ran into this exact issue in https://www.npmjs.com/package/grpc-server-js. I made it an async function to make it seem more synchronous (and because older versions of Node aren't supported), but a callback API makes as much sense.


## Background

In the initial development of the Node gRPC library, the `Server` class method to bind a port, called `bind`, was implemented as a synchronous operation because it was available as an asynchronous operation in the underlying core library. In contrast, in the Node built in `net` module, the `Server` class's `listen` method, which performs a similar function, is asynchronous. In the new pure JavaScript Node gRPC library, the underlying network operations use the `net` module, so it is impossible to implement the `bind` method as a synchronous operation.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

"it was available as an asynchronous operation" --> "it was available as a synchronous operation"?

* @param creds Server credentials object to be used for SSL.
* @param callback Callback to be called asynchronously with the result of binding the port
*/
bindAsync(port: string, creds: ServerCredentials, callback: (port: number)=>void): void;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Should the callback take an error as the first argument? That would be more "Node like" and let this method work with things like util.promisify().

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I am on the fence about that. On one hand, you make a good point about util.promisify() and consistency with other Node operations. On the other hand, the current bind API communicates failure with specific return values instead of throwing errors, so passing an error to the callback would be a greater semantic deviation from the existing API.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It's your call. But if your implementation doesn't end up being compatible with util.promisify() out of the box, you might want to look into custom promisified functions.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Actually, after thinking about it more I think we can have it both ways, or close enough. If we pass an error to the callback on failure, and also pass the number unconditionally, then users who want to can do the same checks with the number that they do now, and we will have compatibility with util.promisify().


## Implementation

I (@murgatroid99) will implement this in the grpc library as soon as this proposal is accpeted, and in the @grpc/grpc-js library as part of the server implementation.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

accpeted -> accepted


## Rationale

The sematics of `bindAsync` would be identical to the semantics of `bind` except it is asynchronous, so the name communicates that. Keeping the semantics and API as similar as possible minimizes the work need to transition between the two. We could also implement the asynchrony using promises, but a callback based API is more consistent with the rest of the existing API. In the future, promise support could be added, perhaps by returning a promise when no callback is provided.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

sematics -> semantics

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants