Skip to content
This repository has been archived by the owner on Jul 3, 2020. It is now read-only.

Node support #93

Merged
merged 19 commits into from
Mar 26, 2016
Merged

Node support #93

merged 19 commits into from
Mar 26, 2016

Conversation

facekapow
Copy link
Contributor

Adds a lot more support for node. Specifically: dns.js (basic, only A records), console.js, process.stdout, process.stderr, stream.js. Couple of notes:

  1. I had to implement stream.js myself because stream-browserify kept crapping out and throwing ReferenceErrors everywhere.
  2. Also about stream.js: I have to implement stream.Transform.
  3. Again, stream.js: I had to copy-paste for stream.Duplex since it inherits both stream.Readable and stream.Writable (if anyone knows how to do multiple inheritance in ES6, please let me know how).
  4. I threw in Promises for some of the functions that take callbacks (they still accept callbacks, though). I figure it's not gonna be long until Node uses them, however, should they just be left as plain old callbacks? If I leave them, should I put Promises on EventEmitter, too?

runtime.stdio.defaultStdio.writeError(String(chunk));
callback();
}
}

Choose a reason for hiding this comment

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

@facekapow why does this file contain es5 and es6 style both? looks odd. Is this okay?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You mean with the callbacks? That's because that's the way the internal API is made in Node (plus, there's really no way to Promise that). It's fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wait, sorry, I think I misunderstood you. The original file by @iefserge was ES5, and my additions were in ES6. It works fine, though.

Choose a reason for hiding this comment

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

Actually I mean that this changes are in es6 style while the whole file is in es5. Just a note. That's ok, I suppose.

Choose a reason for hiding this comment

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

Yep, that's right :)

Copy link
Member

Choose a reason for hiding this comment

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

yeah, I think it's fine, might make sense to upgrade the loader to ES6 at some point too https://github.com/runtimejs/runtime-module-loader

@facekapow
Copy link
Contributor Author

I was able to create a working TCP echo server using this branch:

'use strict';

const runtime = require('runtimejs');
const net = require('net');

const server = net.createServer((socket) => {
  console.log('client...');
  socket.on('end', () => console.log('client end...'));
  socket.write('hello...\r\n');
  socket.pipe(socket);
});
server.listen(9000, () => console.log('echo server online...'));

@iefserge
Copy link
Member

This is awesome! I'm looking through code and going to leave my comments.

1,2. There is a https://www.npmjs.com/package/readable-stream package, that's basically node streams in userland (stream-browserify uses it internally (https://github.com/substack/stream-browserify/blob/master/index.js#L28-L32), maybe we could use that instead? I think implementation of streams is ok, but it's going to be much harder to make sure it works the same way as in node.
3. As far as I know, multiple inheritance is not supported by ES6 extends construct. Something like Object.assign for prototype?
4. I'd say we shouldn't modify or extend any Node APIs, to avoid any compatibility issues.

@facekapow
Copy link
Contributor Author

I tried replacing ./modules/stream.js with readable-stream (and of course, I installed the package), which gave me another error:

Uncaught exception: /node_modules/runtimejs/modules/inherits.js:24: TypeError: Object prototype may only be an Object or null: undefined
TypeError: Object prototype may only be an Object or null: undefined
    at Object.inherits (/node_modules/runtimejs/modules/inherits.js:24:27)
    at /node_modules/runtimejs/node_modules/readable-stream/lib/_stream_readable.js:62:6
    at /node_modules/runtimejs/node_modules/readable-stream/lib/_stream_readable.js:976:3
    at Module.require (__loader:73:9)
    at /node_modules/runtimejs/node_modules/readable-stream/readable.js:13:48
    at /node_modules/runtimejs/node_modules/readable-stream/readable.js:6:28
    at /node_modules/runtimejs/node_modules/readable-stream/readable.js:13:3
    at Module.require (__loader:73:9)
    at Loader.require (__loader:247:25)
    at __loader:290:25

So, for now, I'm going to stick with my implementation and just work on it to support the Node API.
I've removed the Promises from the API and just left the callbacks.

@facekapow
Copy link
Contributor Author

@iefserge Thanks for readable-stream, the problem I was having was that directly replacing it in the __loader was causing errors.

@iefserge
Copy link
Member

@facekapow ah, you have already seen that ;)

My PR might be broken. Managed to get readable-stream kinda working, there is an issue with the echo tcp server. It prints hello... successfully but doesn't echo anything after that. At the same time it works with your implementation perfectly, do you think it might be net-related issue?

I just feel like node streams are so complex and there are so many versions of them, so it's going to be a nightmare to support own implementation. wdyt?

@facekapow
Copy link
Contributor Author

Yeah, I just noticed the problem, when I tested it after committing... :{ I'm going to have to roll back that commit for now. Honestly, I think our implementation would be fine. Any issues that popup would just be fixed. I don't think it'd be such a nightmare...

It's possible it might be net related (since _read does nothing, that might be it)...

@iefserge
Copy link
Member

@facekapow one thing I noticed is that console.log prints to the tty instead of the console. default stdio should probably print to the console too.

@iefserge
Copy link
Member

iefserge commented Feb 6, 2016

@facekapow I think it would be fine to split http into separate PR, so we can merge this first faster

@facekapow
Copy link
Contributor Author

Sorry it took me so long to update, but I finally removed http.js.

@facekapow
Copy link
Contributor Author

I'm currently working on implementing the VM module.

@facekapow
Copy link
Contributor Author

@iefserge I keep getting error: 'v8::Local<T>::Local(S*) [with S = void; T = v8::Context]' is private when trying to compile my code in native-object.cc. My code:

v8::Local<v8::Value> ctx_tmp;
auto maybe_val = arg1->ToObject()->GetPrivate(context, kCtx);
maybe_val.ToLocal(&ctx_tmp);
v8::Local<v8::External> ext = ctx_tmp.As<v8::External>();
v8::Local<v8::Context> ctx = static_cast(v8::Local<v8::Context>)(ext->Value()); // I keep getting the error here
// ext->Value() by itself is okay, it must be something to do with the v8::Local<v8::Context>

Any idea why this is happening? I've tried everything.

@iefserge
Copy link
Member

@facekapow hmm, let's chat on gitter

@facekapow
Copy link
Contributor Author

OK

@facekapow
Copy link
Contributor Author

I think these are all the modules I'm gonna add for now. @iefserge If you want to add anymore, let me know. Otherwise, can this merge?

@facekapow
Copy link
Contributor Author

Apart from making process.stdout and process.stderr output to the QEMU console, I also added process.termout and process.termerr as overrides that go straight to the graphical console.

@piranna
Copy link

piranna commented Mar 25, 2016

Apart from making process.stdout and process.stderr output to the QEMU console, I also added process.termout and process.termerr as overrides that go straight to the graphical console.

Could you be able to explain this a bit more?

results.push({hostname: host, record: 'CNAME', name: readHostname(reader).join('.')});
break;
case queries.MX:
console.log(reader.readUint8());
Copy link
Member

Choose a reason for hiding this comment

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

@facekapow debug?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I forgot.

@iefserge
Copy link
Member

@facekapow looks like console.log outputs extra \n

@iefserge
Copy link
Member

@piranna there are two consoles

  • console that QEMU outputs to the terminal (works through serial port) - console.log prints here by default
  • graphical console in QEMU window

@facekapow
Copy link
Contributor Author

@iefserge About the eshttp module you mentioned earlier, I think a wrapper around it would make a pretty good http module 👍.

@piranna
Copy link

piranna commented Mar 25, 2016

How is that they are not the same?
El 25/3/2016 22:54, "Serge" notifications@github.com escribió:

@piranna https://github.com/piranna there are two consoles

  • console that QEMU outputs to the terminal (works through serial
    port) - console.log prints here by default
  • graphical console in QEMU window


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
#93 (comment)

@facekapow
Copy link
Contributor Author

@piranna The QEMU serial port console is the one that outputs to your system terminal. The graphical console is the one created by runtime.js in the QEMU window.

@piranna
Copy link

piranna commented Mar 25, 2016

@piranna The QEMU serial port console is the one that outputs to your system terminal. The graphical console is the one created by runtime.js in the QEMU window.

I understand the difference, but I don't understand why there are different... Maybe I'm too much used to deal with QEmu and Linux where you get one or the other...

@iefserge
Copy link
Member

graphical console has a command prompt, useful for debugging.

@@ -290,13 +290,17 @@
const stream = loader.require('stream');
class StdoutStream extends stream.Writable {
_write(chunk, encoding, callback) {
__SYSCALL.log(String(chunk));
var out = String(chunk);
if (out.substring(out.length-1) === '\n') out = out.substring(0, out.length-1);
Copy link
Member

Choose a reason for hiding this comment

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

hm, I think this is an issue with __SYSCALL.log, it shouldn't add \n at the end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is, but if you remove the newline from __SYSCALL.log, the output at startup is output on the same line.

Copy link
Member

Choose a reason for hiding this comment

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

maybe add a __SYSCALL.write?

@facekapow
Copy link
Contributor Author

There's only one little thing. Should I add a runtime.console? An instance of Console with its output hooked up to the graphical console? Or just leave everything the way it is?

@iefserge
Copy link
Member

Two consoles would be pretty confusing, I think graphical one is more like a debug tool. Should be fine as it is.

@facekapow
Copy link
Contributor Author

Ok.

@facekapow
Copy link
Contributor Author

Any last minute bugs or anything?

@iefserge
Copy link
Member

@facekapow this looks great, very exciting! Tests coverage would be cool, but there are still a few issues with the test runner, so I'd say it's fine to merge now 👍
I'll try to figure out tests (and linting) later at some point.

@facekapow facekapow merged commit 6278e61 into master Mar 26, 2016
@facekapow facekapow changed the title Node support - Work In Progress Node support Mar 26, 2016
@facekapow
Copy link
Contributor Author

Bump kernel and JS versions?

@iefserge
Copy link
Member

@facekapow not yet, I'm looking into Travis CI based automatic deployment, because prebuilt binaries need to be released too

@facekapow
Copy link
Contributor Author

Deleted my last comment, it was completely wrong, sorry.

@iefserge iefserge deleted the node-support branch March 26, 2016 17:15
@iefserge
Copy link
Member

@facekapow yeah, I think using releases would be fine.

@facekapow
Copy link
Contributor Author

Oh, ok. Guess I wasn't completely wrong.
Comment I deleted:

If you deployed through Github Releases, you could just use Travis CI's Github Releases. All you have to do to support Github Releases is add the extra path components to the download URL in runtime-cli.

@iefserge
Copy link
Member

@facekapow this has been released 👍
Also configured Travis CI to build releases and publish tags to npm automatically. runtime-cli major update required though.

@facekapow
Copy link
Contributor Author

@iefserge Great! When I get home I'll patch up runtime-cli.

edit: nevermind, you already did.

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

Successfully merging this pull request may close these issues.

None yet

4 participants