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.