33
Disclaimer ;-) Doesn't necessarily reflect the views of IBM, or any of my Node.js collaborators... 1

Node.js API pitfalls

Embed Size (px)

Citation preview

Disclaimer ;-)

Doesn't necessarily reflect the views of IBM, or any of my Node.js collaborators...

1

nextTick

•  [ ] in next tick of the event loop •  [ ] immediately after A returns

2

process.nextTick(function() { // Called ... });

nextTick

•  [ ] in next tick of the event loop •  [x] immediately after A returns

3

process.nextTick(function() { // Called ... });

setImmediate

•  [ ] in next tick of the event loop •  [ ] immediately after A returns

4

setImmediate(function() { // Called ... });

setImmediate

•  [x] in next tick of the event loop •  [ ] immediately after A returns

5

setImmediate(function() { // Called ... });

nextTick vs setImmediate

•  nextTick: adds callback to queue to be called immediately •  setImmediate: adds callback to queue to be called next tick

6

worker.kill()

7

var cluster = require('cluster'); if (cluster.isMaster) {

cluster.fork() .on('online', function() { this.kill('SIGHUP'); }) .on('exit', function() { console.log('Exit'); });

} else { process.on('SIGHUP', function() {

console.log('Hup'); }); }

worker.kill()

•  [ ] "Hup" •  [ ] "Exit" •  [ ] "Hup" and "Exit" •  [ ] No output

8

var cluster = require('cluster'); if (cluster.isMaster) {

cluster.fork() .on('online', function() { this.kill('SIGHUP'); }) .on('exit', function() { console.log('Exit'); });

} else { process.on('SIGHUP', function() { console.log('Hup'); }); }

worker.kill()

•  [ ] "Hup" •  [x] "Exit" •  [ ] "Hup" and "Exit" •  [ ] No output

9

var cluster = require('cluster'); if (cluster.isMaster) {

cluster.fork() .on('online', function() { this.kill('SIGHUP'); }) .on('exit', function() { console.log('Exit'); });

} else { process.on('SIGHUP', function() { console.log('Hup'); }); }

worker.kill() - what is it really?

•  Use worker.process.kill() if you want to signal the worker •  Asymetric with worker.send(), worker.on('message', ...), etc.

10

Worker.prototype.kill = function(signo) { var proc = this.process; this.once('disconnect', function() { this.process.kill(signo || 'SIGTERM'); }); this.disconnect();

};

worker.suicide - kill the worker

•  [ ] true •  [ ] false

11

var cluster = require('cluster'); if (cluster.isMaster) {

cluster.fork() .on('online', function() { this.kill('SIGTERM'); }) .on('exit', function() { // this.suicide is .... });

} else { }

worker.suicide - kill the worker

•  [x] true •  [ ] false

12

var cluster = require('cluster'); if (cluster.isMaster) {

cluster.fork() .on('online', function() { this.kill('SIGTERM'); }) .on('exit', function() { // this.suicide is .... });

} else { }

worker.suicide - exit the worker

•  [ ] true •  [ ] false

13

var cluster = require('cluster'); if (cluster.isMaster) {

cluster.fork() .on('exit', function() { // this.suicide is .... });

} else { process.exit(0); }

worker.suicide - exit the worker

•  [ ] true •  [x] false

14

var cluster = require('cluster'); if (cluster.isMaster) {

cluster.fork() .on('exit', function() { // this.suicide is .... });

} else { process.exit(0); }

worker.suicide - what does it mean?

•  worker.disconnect() in parent (implicitly done by worker.kill()) •  process.disconnect() in worker

15

Actual meaning: "orderly exit"

url.parse/format

16

var url = require('url'); var uri = url.parse('http://example.com:8080/path'); uri.host = 'ibm.com'; console.log(url.format(uri));

•  [ ] yes •  [ ] no

Prints http://ibm.com:8080/path ...

url.parse/format

17

var url = require('url'); var uri = url.parse('http://example.com:8080/path'); uri.host = 'ibm.com'; console.log(url.format(uri));

•  [ ] yes •  [x] no: http://ibm.com/path

Prints http://ibm.com:8080/path ...

url.parse/format

•  host is "example.com:8080" •  hostname is "example.com"

18

url.parse/format

19

var url = require('url'); var uri = url.parse('http://example.com:8080/path'); uri.hostname = 'ibm.com'; console.log(url.format(uri));

•  [ ] yes •  [ ] no

Prints http://ibm.com:8080/path ...

url.parse/format

20

var url = require('url'); var uri = url.parse('http://example.com:8080/path'); uri.hostname = 'ibm.com'; console.log(url.format(uri));

•  [ ] yes •  [x] no: http://example.com:8080/path

Prints http://ibm.com:8080/path ...

url.parse/format

•  hostname and port are ignored if host is present...

21

url.parse/format

22

var url = require('url'); var uri = url.parse('http://example.com:8080/path'); delete uri.host; uri.hostname = 'ibm.com'; console.log(url.format(uri));

•  http://ibm.com:8080/path, finally!

url.parse/format

•  parse: "http://example:8080": – port is 8080 – host is "example:8080"... why not hostport? – hostname is "example"... why not host?

•  format: hostname and port are ignored if hostname is present – shouldn't they be prefered if present?

23

path.parse/format

24

var path = require('path'); var bits = path.parse('some/dir/index.txt'); // has: .name, .ext bits.ext = '.html'; console.log(path.format(bits));

Logs some/dir/index.html...

•  [ ] yes •  [ ] no

path.parse/format

25

var path = require('path'); var bits = path.parse('some/dir/index.txt'); bits.ext = '.html'; console.log(path.format(bits));

Logs some/dir/index.html...

•  [ ] yes •  [x] no: some/dir/index.txt

path.parse/format

26

var path = require('path'); var bits = path.parse('some/dir/index.txt'); console.log(bits.base); // > index.txt delete bits.base bits.ext = '.html'; console.log(path.format(bits));

Logs some/dir/index.html... •  [ ] yes •  [ ] no

Its probably like url...

path.parse/format

27

var path = require('path'); var bits = path.parse('some/dir/index.txt'); console.log(bits.base); // > index.txt delete bits.base bits.ext = '.html'; console.log(path.format(bits));

Logs some/dir/index.html...

•  [ ] yes •  [x] no: some/dir/

path.parse/format

28

var path = require('path'); var bits = path.parse('some/dir/index.txt'); bits.base = bits.name + '.html'; console.log(path.format(bits)); // > some/dir/index.html

Its just completely different, format always ignores name and ext.

Correct:

streams v1, 2, 3

29

Note that, for backwards compatibility reasons, removing 'data' event handlers will not automatically pause the stream. Also, if there are piped destinations, then calling pause() will not guarantee that the stream will remain paused once those destinations drain and ask for more data.

From https://nodejs.org/api/stream.html#stream_class_stream_readable:

streams v1, 2, 3

30

Note that, for backwards compatibility reasons, removing 'data' event handlers will not automatically pause the stream. Also, if there are piped destinations, then calling pause() will not guarantee that the stream will remain paused once those destinations drain and ask for more data.

From https://nodejs.org/api/stream.html#stream_class_stream_readable:

When can we delete backwards compat to v0.8?

Question

•  Laurie Voss (@seldo), NPM, Nov. 28, 2015

31

What kind of node do you want: a good one? or a (mostly) v0.8 compatible one?

@octetcloud As of right now, 30.4% of registered npm accounts are less than 6 months old.

Answer

•  github, twitter, etc.. •  Be tolerant (or intolerant) of breakages, but what

you say will effect what happens.

32

Its yours (and a lot of other people's) Node.js, speak out:

Flames to:

•  github: @sam-github •  email: [email protected] •  twitter: @octetcloud •  talk source: https://gist.github.com/sam-github/4c5c019b92cf95fb6571, or

https://goo.gl/2RWpqE

33