Skip to content

Syncify with a Subprocess. #402

@ariporad

Description

@ariporad

Hi Everyone,

I just wanted to open a discussion about something that I've been working on, before I work too hard on it.

I've talked about this before, but here's my idea:

  • Because of the way Node works, it's a lot easier to write things asyncly.
  • But we want shelljs commands to be sync.
  • Therefore, it would be nicer if we could syncify things,
  • However, this doesn't work:
function syncSomething(arg1) {
    var ret = null, err = null, done = false;
    something(arg1, function (err, ret) {
        // We will never get here, because the event loop will never be clear, so the callback can never start.
        ret = _ret;
        err = _err;
        done = true;
    });
    while(!done) continue;
    if (err) throw err;
    return ret;
}
  • So, the only way to syncify (at least without a native extension) something is to make a second event loop.
  • The only way to do that is to start a second process.
  • So, what we could do is this:
  1. After all the argument parsing, common.wrap could do this:
// ...
if (callback || options.cp === false) {
    func.apply(null, args.concat([callback]));
} else {
    if (!this.cp) this.cp = new ChildProcess();
    return this.cp.cmd(this.name, args);
}
  1. ChildProcess.prototype.cmd could do this:
ChildProcess.prototype.cmd = function(cmd, args) {
    var id = Math.random().toString();
    write({ type: 'cmd', cmd, args, id }); // I've already written read/write, they work, so I won't go into it here.
    var ret, err, done;
    while (!done) {
        var events = read();
        for (var i = 0; i < events.length; ++i) {
            if (events[i].type === 'cmd' && events[i].id === id) {
                ret = events[i].ret;
                err = events[i].err;
                done = true;
            }
        }
    }
    if (err) throw err;
    return ret;
}
  • But since I realized that this was going to basically be a rewrite of shelljs, I thought we should discuss it first.
  • Also, @levithomason setup a really awesome build and lint system for shelljs/shx, so if we're going to re-write it, I think we might want to get something similar. (@levithomason, would you be interested/willing in working this?)

Things this would fix (@shelljs/contributors, feel free to edit this and add stuff):

So, @shelljs/contributors and @shelljs/shx, what are your thoughts on this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedmedium priorityquestionQuestion from a user (which may not require code/documentation changes to the project)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions