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

lib: prepare code for metarhia-common and metasync #246

Closed
wants to merge 2 commits into from

Conversation

tshemsedinov
Copy link
Member

@aqrln This PR is not complete, just for your interest. I'll do it in multiple steps and I may need your help.

@tshemsedinov tshemsedinov requested a review from aqrln June 28, 2017 21:46
@tshemsedinov tshemsedinov changed the title lib: prepare code to use metarhia-common lib: prepare code for metarhia-common and metasync Jul 18, 2017
@tshemsedinov
Copy link
Member Author

@aqrln done, but I rebased this branch with branch style-and-opt to avoid conflicts with eb7a704 lib: refactor return style so PR includes commit from different PR.

@tshemsedinov
Copy link
Member Author

@aqrln rebased again

@@ -21,24 +23,25 @@ class Application {
// callback - method callback
//
callMethod(connection, interfaceName, methodName, args, callback) {
const cb = common.cb(callback);
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we need it here. Connection#callMethod() takes care of optional callbacks. This is an internal method and we are pretty safe making the last argument required.

if (callback) {
callback(error, sessionId);
}
callback(error, sessionId);
Copy link
Member

Choose a reason for hiding this comment

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

What is the reason of this change?

}

this._connection.callMethod(this._interfaceName, methodName, args, callback);
const cb = common.cbExtract(args);
Copy link
Member

Choose a reason for hiding this comment

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

Can we please call it callback? I'd prefer to use descriptive names when possible.

lib/socket.js Outdated
@@ -83,12 +85,12 @@ class Transport extends EventEmitter {
}

const socketFactory = connect => (...options) => {
const callback = common.extractCallback(options);
const cb = common.cbExtract(options);
Copy link
Member

Choose a reason for hiding this comment

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

Ditto.

@@ -27,10 +29,10 @@ const common = require('./common');
const newConnectFn = (
connFactory, transportClass
) => (appName, client, ...options) => {
const callback = common.extractCallback(options);
const cb = common.cbExtract(options);
Copy link
Member

Choose a reason for hiding this comment

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

Ditto.

let errored = false;
const len = interfaces.length;
let count = 0;
const pCollector = metasync.collect(interfaces.length);
Copy link
Member

Choose a reason for hiding this comment

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

Maybe something like proxiesCollector or even just collector. That lone "p" letter doesn't help readability much and looks like hungarian notation.

@@ -80,14 +82,15 @@ class Transport extends EventEmitter {
// appProvider - client application provider
//
const socketFactory = (url, callback) => {
const cb = common.cb(callback);
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure whether we need it here, it may be handled at a higher level.

/cc @lundibundi

Copy link
Member

Choose a reason for hiding this comment

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

This is also an internal function, there is always a callback here.

@@ -124,13 +126,13 @@ const initServer = function(options, httpServer) {
// is established.
//
const connectionFactory = (webSocketConfig, ...options) => {
const callback = common.extractCallback(options);
const cb = common.cbExtract(options);
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer it to be callback.

"version": "4.11.8",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
"integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
"version": "5.2.2",
Copy link
Member

Choose a reason for hiding this comment

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

There's a huge deal of unrelated changes and version bumps. Can you please revert all the changes to package.json and package-lock.json and run npm i metasync metarhia-common anew?

Copy link
Member Author

Choose a reason for hiding this comment

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

@aqrln but this PR requires metasync and metarhia-common on package.json

Copy link
Member

Choose a reason for hiding this comment

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

Yes. But running npm install metasync metarhia-common will add them to package.json too.

tools/common.js Outdated

const writeFile = promisify(fs.writeFile);

module.exports = {
Copy link
Member

Choose a reason for hiding this comment

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

This change is unrelated. Can you please split it into another PR?

@metarhia metarhia deleted a comment from lundibundi Jul 22, 2017
@tshemsedinov tshemsedinov force-pushed the use-metarhia-common branch 5 times, most recently from ce962f5 to 6978e61 Compare July 22, 2017 12:40
@tshemsedinov
Copy link
Member Author

@aqrln see dff1d34 it is related to this PR because of naming but extracted to separate commit.

@tshemsedinov
Copy link
Member Author

@aqrln rebased and ready

@@ -75,13 +75,13 @@ module.exports = class LineProcessor {
callback(reportMissingArgument('Host'));
return;
}
const args = utils.split(tokens, ' ', 2);
let [scheme, authority] = utils.split(args[0], '://', 1, true);
const args = autocomplete.split(tokens, ' ', 2);
Copy link
Member

Choose a reason for hiding this comment

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

split function here has nothing to do with autocomplete whatsoever, it is just used to split up the arguments provided by the user in CLI.

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree, but see https://github.com/metarhia/jstp/pull/246/files#r132857348 We must arrange such common utilities to have code consistency over project, Meterhia stack and JS stories in general.

package.json Outdated
@@ -37,6 +37,8 @@
"dependencies": {
"semver": "^5.4.1",
"uuid": "^3.1.0",
"metarhia-common": "0.0.19",
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't it be: "metarhia-common": "^0.0.19",?

Copy link
Member

Choose a reason for hiding this comment

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

@nechaido both 0.0.19 and ^0.0.19 mean the same thing. Caret ranges only allow updates that don't modify the leftmost non-zero part of the version.


module.exports = {
filterKeys,
split,
Copy link
Member

Choose a reason for hiding this comment

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

Why have you moved rsplit to metarhia-common but have not moved split?

Copy link
Member Author

Choose a reason for hiding this comment

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

I changed rsplit to common.rsection because it is not compatible with String.prototype.split() This split is also not compatible with String.prototype.split() so I think we will either rename it or use String.prototype.split() instead.

lib/socket.js Outdated
@@ -84,7 +85,7 @@ class Transport extends EventEmitter {

const socketFactory = (connect) => {
const resultConnectFn = (...options) => {
const callback = common.extractCallback(options);
const callback = common.cbExtract(options);
Copy link
Member

Choose a reason for hiding this comment

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

extractCallback and cbExtract are not equivalent, the latter has a lot of checks that are completely unnecessary here. I think it's better to place extractCallback in common and rename cbExtract to something that will represent its purpose, like cbWrapExtract.

Copy link
Member Author

@tshemsedinov tshemsedinov Aug 13, 2017

Choose a reason for hiding this comment

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

Yes, I agree, in metarhia-common v0.0.21 we have safeCallback (renamed cbExtract) and unsafeCallback (renamed cbUnsafe). I placed your code of extractCallback into common.unsafeCallback because it's optimal implementation. Also I renamed common.cb to once because once will be clear and native for JS world.

Copy link
Member Author

Choose a reason for hiding this comment

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

In this case user can call it without callback so we need common.safeCallback

Copy link
Member

Choose a reason for hiding this comment

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

This is an internal function that always has callback, the user cannot call it.

Copy link
Member Author

Choose a reason for hiding this comment

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

This callback comes from jstp.net.connect and jstp.net.connectAndInspect and tls/ws/wss analogs. Try to remove this callack in test/node/transport-net-tcp.js for example.

Copy link
Member

Choose a reason for hiding this comment

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

At the time it throws a TypeError:

> jstp.net.connect('name', null, 123);
undefined
> TypeError: callback is not a function
    at connFactory (/home/nechaido/Projects/metarhia/jstp/lib/transport-common.js:35:7)
    at Socket.onceErrorListener (/home/nechaido/Projects/metarhia/jstp/lib/socket.js:91:9)
    at Object.onceWrapper (events.js:316:30)
    at emitOne (events.js:115:13)
    at Socket.emit (events.js:210:7)
    at emitErrorNT (internal/streams/destroy.js:64:8)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickDomainCallback (internal/process/next_tick.js:218:9)

I am ok with it. connectis not a function that can be called without callback.

Copy link
Member Author

Choose a reason for hiding this comment

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

We need to avoid throwing, it terminates process, it's better to bubble an error to upper level without process termination.

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 can agree that connect is client-side function, client-side code is less durable in termination/restarting meaning.

Copy link
Member

Choose a reason for hiding this comment

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

@tshemsedinov, but it's a completely natural behavior in Node.js for TypeError to occur whenever you provide invalid arguments to the function (which is the case with providing no callback to the connect function).
This means that the user gets TypeError thrown only when he/she is using the library incorrectly.

@@ -29,7 +31,7 @@ const common = require('./common');
const newConnectFn = (
connFactory, transportClass
) => (app, client, ...options) => {
const callback = common.extractCallback(options);
const callback = common.cbExtract(options);
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

In this case user can call it without callback so we need common.safeCallback

Copy link
Member

Choose a reason for hiding this comment

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

In this case not providing a callback is both an error and strange (you are calling a function to create a connection and not expecting a result), that's why I used extract here.

@@ -73,30 +75,21 @@ const newConnectFn = (
const newConnectAndInspectFn = (connFactory, transportClass) => {
const connect = newConnectFn(connFactory, transportClass);
return (app, client, interfaces, ...options) => {
const callback = common.extractCallback(options);
const callback = common.cbExtract(options);
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

In this case user can call it without callback so we need common.safeCallback

Copy link
Member

Choose a reason for hiding this comment

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

Same as #246 (comment).

@@ -124,7 +125,7 @@ const initServer = function(options, httpServer) {
// is established.
//
const connectionFactory = (webSocketConfig, ...options) => {
const callback = common.extractCallback(options);
const callback = common.cbExtract(options);
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

In this case user can call it without callback so we need common.safeCallback

Copy link
Member

Choose a reason for hiding this comment

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

Same as #246 (comment).

@@ -17,7 +18,7 @@ const errors = require('./errors');
//
class Application {
constructor(name, api, version) {
[this.name, this.version] = common.rsplit(name, '@');
[this.name, this.version] = common.rsection(name, '@');
Copy link
Member

Choose a reason for hiding this comment

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

I think that it's better to update rsplit function to support cases from python where I actually took it from and name it as such.

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree, we need full rsplit so I added issue here: metarhia/common#91 but I think in this place rsection is ok because it is simpler and in multiple other cases rsection will be optimal.

@tshemsedinov
Copy link
Member Author

In most cases we use extractCallback (new name unnsafeCallback) to get callback from user-defined connection function, so user can pass callback optionally. If no callback passed exception will throw. In such cases we may choose one of the following ways:

  • Use unsafeCallback and declare callback as required, so user will be responsible for inappropriate use.
  • Implement requiredCallback that requires last argument to be callback and throw exception otherwise.
  • Use safeCallback and have no problems but overhead.
  • Change safeCallback behavior: use empty function but remove prevention of multiple calls, so it will be safe enough for above this cases. For more strict cases we can implement onceCallback.

I'd prefer to have in metarhia-common all those cases:

  • unsafeCallback(array): function or null
  • safeCallback(array): function or emptiness
  • requiredCallback(array): function or throw
  • onceCallback(array): once(function) or emptiness

@metarhia/jstp-core

@belochub
Copy link
Member

Closing this PR, since it's become outdated to the point where it's easier to rewrite it from scratch compared to resolving all of the merge conflicts when rebasing on master.
I will also create a corresponding issue to keep as a reminder (as proposed by @tshemsedinov).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants