node.js Domain æ代ã®ã¨ã©ã¼å¦çã®ã³ã¼ãã£ã³ã°ãã¿ã¼ã³
id:kazuhooku ããã®è¨äº node.js におけるエラー処理のコーディングパターン (もしくは非同期 JavaScript における例外処理ã
ãã¤ã¹ã§ãï¼ ãªãã¨ç´ æ´ãããã¿ã¤ãã³ã°ã§ã®ããã°ã§ããããï¼
ã東京Node学園 5時限目ã㧠id:koichik ããã®ãã¬ã¼ã³ã§ node-v0.7.8 ãã isaacs ç Domain ãå°å ¥ãããã¨ããçºè¡¨ãããã¾ããããäºå®éãæ¨æ¥ Domain æ©è½ä»ãã® node-v0.7.8 ããªãªã¼ã¹ããã¾ããã
ãããDomain ã®ããã¥ã¡ã³ãä»ãã§ãã http://nodejs.org/docs/v0.7.8/api/domain.html
ã¡ããã© id:kazuhooku ããã®è¨äºã®ä¾ã¯ node.js ã®æ°æ©è½ Domain ãæç§æ¸éãã«é©å¿ããã¨ã©ããªãã®ãç´¹ä»ããã®ã«ã´ã£ããã®ãé¡ãªã®ã§
Node.js v0.8 ã®æ°æ©è½ Domain ã®ä½¿ãæ¹
ã«ã¤ãã¦æ¸ããã¦ããã ãã¾ãã
Node.jsã®æ°æ©è½ Domain ã使ã
ã¾ããã¡ã¤ã³ãå©ç¨ãã¦ã¨ã©ã¼å¦çããã«ã¯
- domain ã¢ã¸ã¥ã¼ã«ã® require()
- domain ãªãã¸ã§ã¯ãã®çæ
- domain ã§åããã¨ã©ã¼ãªã¹ãã¼ã®ç»é²
- domain ã¨ã¨ã©ã¼ãã³ããªã³ã°ã¨ã®çµã³ä»ã
- eventEmitter ã®å ´å㯠Domain.add
- é¢æ°ã®å ´å㯠Domain.bind
ã¨ãã£ã段åããå¿
è¦ã§ãã
id:kazuhooku ããã®è¨äºã«ããã³ã¼ãããDomain 使ã£ããã©ã®ãããªã³ã¼ãã£ã³ã°ãã¿ã¼ã³ãèãããããããã¤ä¾ç¤ºãã¦ã¿ããã¨æãã¾ããã(注ï¼åä½ã«ã¯ node-v0.7.8 以éãå¿
è¦ã§ããï¼
ä»å3ã¤ã®ãã¿ã¼ã³ã§èãã¾ããã
- ãã¿ã¼ã³1: ã³ã¼ã«ããã¯é¢æ°ã«ãã¡ã¤ã³ãçµã³ã¤ãã¦ã¨ã©ã¼ãã³ããªã³ã°ãè¡ã
- ãã¿ã¼ã³2: é¢æ°å¼ã³åºãæã«ãã¡ã¤ã³ãçµã³ã¤ãã¦ã¨ã©ã¼ãã³ããªã³ã°ãè¡ã
- ãã¿ã¼ã³3: é¢æ°å®ç¾©æã«ãã¡ã¤ã³ãçµã³ã¤ãã¦ã¨ã©ã¼ãã³ããªã³ã°ãè¡ã
ã§ã¯ãµã³ãã«ã³ã¼ãã¨ã¨ãã«ãã¡ã¤ã³ã使ã£ãã³ã¼ãã£ã³ã°ãã¿ã¼ã³ãä¾ç¤ºãã¦ããã¾ãã
ãã¿ã¼ã³1: ã³ã¼ã«ããã¯é¢æ°ã«ãã¡ã¤ã³ãçµã³ã¤ããæ¹æ³
ã¾ãã¯ã¨ã©ã¼ãªãã¸ã§ã¯ããå«ãã³ã¼ã«ããã¯ã§ãã¡ã¤ã³ã¨ã¨ã©ã¼ãçµã³ã¤ããå ´åã§ãã
// domain_sample1.js var domain = require('domain'); var fs = require('fs'); var d = domain.create(); function countChars(filename, callback) { // ã³ã¼ã«ããã¯ã«ç´æ¥ãã¡ã¤ã³ããã¤ã³ã fs.readFile(filename, 'utf-8', d.bind(function(err, data) { if (err) throw err; callback(data.length); })); } function main(args) { countChars(args[0], function(length) { console.log(length); }); } d.on('error', function(err) { console.log(err.message); }); main(process.argv.slice(2))
unixjp:~/tmp/github/node> ./node domain_sample1.js hoge ENOENT, open 'hoge'
ã¯ããããããªã³ã¼ãã«ãªãã¾ãããã
ãã¿ã¼ã³2: é¢æ°å¼ã³åºãã«æã«ãã¡ã¤ã³ãçµã³ã¤ããæ¹æ³
é¢æ°ãå¼ã³åºãã¨ãã«ãã¤ã³ããããå ´åã¯ã
// domain_sample2.js var fs = require('fs'); var domain = require('domain'); var d = domain.create(); function countChars(filename, callback) { fs.readFile(filename, 'utf-8', function(err, data) { if (err) throw err; callback(data.length); }); } function main(args) { // é¢æ°ãå¼ã³åºãæã«ãã¡ã¤ã³ããã¤ã³ãããã (d.bind(countChars))(args[0], function(length) { console.log(length); }); } d.on('error', function(err) { console.log(err.message); }); main(process.argv.slice(2));
ãªæãã§ãã
ãã¿ã¼ã³3: é¢æ°å®ç¾©ã«ãã¡ã¤ã³ãçµã³ã¤ããæ¹æ³
é¢æ°å®ç¾©ç´å¾ã«ãã¤ã³ããããªãã
// domain_sample3.js var fs = require('fs'); var domain = require('domain'); var d = domain.create(); function countChars(filename, callback) { fs.readFile(filename, 'utf-8', function(err, data) { if (err) throw err; callback(data.length); }); } // é¢æ°å®ç¾©ç´å¾ã«ãã¡ã¤ã³ã«ãã¤ã³ã countChars = d.bind(countChars); function main(args) { countChars(args[0], function(length) { console.log(length); }); } d.on('error', function(err) { console.log(err.message); }); main(process.argv.slice(2));
ã¨ãã£ãããã«ãªãã¾ãã
ã¾ã¨ã
ä»ã«ã¯ event.EventEmitter ã®ã¨ã©ã¼ã¨çµã³ä»ãããå ´å㯠Domain.bind() ã§ã¯ãªã Domain.add() ããã°ãã¡ã¤ã³å
ã®ã¨ã©ã¼å¦çã§æ±ãã¾ãã
ãã®ããã« Domain ã®æ©è½ã使ãã¨ããã¾ã§ã¨éã£ãå½¢ã§ã¨ã©ã¼ãã³ããªã³ã°ãããå¯è½æ§ãåºãããå¾æ¥ããå¯èªæ§ã®é«ãã»ç°¡æ½ãªã³ã¼ããæ¸ããããã«ãªãã§ãããã
追è¨: Domain.intercept() ã使ã
id:koichik ããããã®ã³ã¡ã³ãã«ãããã domain.bind(cb, true) ã 㨠throw ããªãã¦ãã¨ã©ã¼ãã²ã£ããã¦ããã¾ããï¼å¼ã°ããé¢æ°ã®ç¬¬ä¸å¼æ°ã Error ã¤ã³ã¹ã¿ã³ã¹ã§ãããã¨ãæ¡ä»¶ã§ããã©ï¼ ãããã¾ã¨ã㦠domain.intercept() ã¨ããé¢æ°ã«ãªã£ã¦ã¾ãã
ã¨ãããã¨ã§ domain.intercept() ã使ãã¨ãã£ã¨ãã£ããã«æ¸ãã¾ãã
// domain_sample4.js var domain = require('domain'); var fs = require('fs'); var d = domain.create(); function countChars(filename, callback) { fs.readFile(filename, 'utf-8', d.intercept(function(err, data) { callback(data.length); })); } function main(args) { countChars(args[0], function(length) { console.log(length); }); } d.on('error', function(err) { console.log(err.message); }); main(process.argv.slice(2));
unixjp:~/tmp/github/node> ./node domain_sample4.js hoge ENOENT, open 'hoge'
ãããã¨ããããã¾ãã > id:koichik ããã
追è¨ã®è¿½è¨ï¼ Domain.run() ã使ãã
ã¾ãã¾ã id:koichik ãããã twitter çµç±ã§ Domain.run() ã®ä½¿ãæ¹ãæãã¦ããã ãã¾ãããï¼å®ã¯ããã¥ã¢ã«ã«ã¯è¨è¼ããã¦ãã¾ãããã©ï¼â id:koichik ããããã®ã³ã¡ã³ã㧠public API ã¨ãã¦ããã¥ã¡ã³ãåããã¾ãããhttps://github.com/joyent/node/commit/c0a9985da7a7d3f6ebc51805d6955d92b1bd6e78
ããã使ãã¨ä¸è¨ãã¿ã¼ã³2(é¢æ°å¼ã³åºãã«æã«ãã¡ã¤ã³ãçµã³ã¤ããæ¹æ³)ã®ã³ã¼ã㧠(d.bind(fn))(args) ã¨æ¸ãã¦ããã¨ããã d.run(function() {fn(args)} ã¨æ¸ãã¦ããã£ã¨ãã£ãããã¾ãã
// domain_sample5.js var fs = require('fs'); var domain = require('domain'); var d = domain.create(); function countChars(filename, callback) { fs.readFile(filename, 'utf-8', function(err, data) { if (err) throw err; callback(data.length); }); } function main(args) { // é¢æ°ãå¼ã³åºãæã«ãã¡ã¤ã³ããã¤ã³ãããã d.run(function() { countChars(args[0], function(length) { console.log(length); }); }); } d.on('error', function(err) { console.log(err.message); }); main(process.argv.slice(2));