Tue 22 May 2018 — Wed 23 May 2018

Node JS

NodeJS is a JavaScript interpreter which runs on your machine without involving a web browser. It's based on Google's V8 engine.

The guides page is a reasonably helpful starting place, but probably not very comprehensive. It's probably actually unhelpful for people who aren't at least a bit familiar with what's going on already.

Recent versions of NodeJS support almost all of EcmaScript 2018. The main exception being tail calls. http://node.green/

HTTP

NodeJS has a web server built into it, so it effectively works something like php-fpm, uwsgi, gunicorn, or Jetty.

You can use this server with the http module. It provides a method createServer(requestHandler), which returns a server.

To start your server instance, use the listen(port, hostname, someMoreCode).

"use strict";

/*global module, require, global*/

const http = require("http");

const server = http.createServer((request, response) => {
    response.statusCode = 200; response.setHeader("Content-Type",
    "text/plain"); response.end("Oi oi savaloy!"); });

server.listen(80, "localhost", () => { console.log("Server
    started."); });

People commonly use the ExpressJS framework, which provides routing, and lets you plug in modules which can have an effect before the final routing piece happens.

Useful properties on a request object:

method
url
headers
a processed dictionary
rawHeaders

Useful events on a request object:

data
read a chunk of request data
error

Useful things on a response object:

statusCode
setHeader()
write()
end()

For making HTTP requests, use the http.request() or http.get() methods.

All of this is, of course, happening async.

Non-blocking IO and asynchrony

NodeJS automatically runs a reactor loop (also called an event loop) for every program you run on it. You should write your programs in an asynchronous, non-blocking way to take advantage of this.

NodeJS has an event loop (for JavaScript) on one thread, and a worker thread pool (for C, using libuv).

You need to make sure that any long-running CPU or other blocking operations are farmed out to a worker task, or possibly to another process entirely (which may not be NodeJS).

Some of the built-in modules (file system, DNS, crypto, zip/unzip) create worker tasks for you.

Tasks are picked up as follows:

event loop
next available thing found using epoll
worker threads
next in the queue

Overall, NodeJS is designed to be fast when IO dominates performance.

Timers

setTimeout(fn, time)
call a function later
setImmediate(fn)
call a function soon
setInterval(fn, timeDelta)
repeatedly call a function

These functions return objects which we can use to fiddle with the scheduling.

There are corresponding clearTimeout, clearImmediate and clearInterval functions, for when you have regrets.

Timers also have their own special stage of the event loop (except for setImmediate, which jumps the queue). This means they can get delayed a lot if you keep on scheduling callbacks.

There's a function process.nextTick(), which pushes the event loop to the next timers phase.

Debugging

Run node --inspect my-file.js, or send the SIGUSR1 signal with kill -SIGUSR1 node to turn on debugging mode.

You can also run node --inspect-brk my-file.js to immediately break on the first line of the file.

This exposes port 9229 on localhost.

There are a few things that can connect to this:

Chrome developer tools
type about:inspect into the URL bar
node-inspector
obsolete
(no term)
Visual Studio

Chrome developer tools is magic, and can automatically pick up a node-js debugging instance if you quit and then restart.

Profiling

Profiling is a two stage process.

First you output some incomprehensible logs using node --prof. This will make us a .log file in the working directory.

Next run node --prof-process my-log.log to turn it into a useful form.

TODO Filesystems

Import the fs module.

Most operations have a synchronous equivalent, for example readFile is the asyncrhonous version of readFileSync.

Useful functions:

readFile
unlink

Native API

https://nodejs.org/api/n-api.html

This is for calling out to programs or libraries written in other languages which expose bindings (usually C, C++, Fortran).

I don't care about this for now, and so am ignoring it.