プロセスをtelnetから制御する

前から触ってみたかったclusterモジュールを触って見ました。
ただforkとかしてもつまらないと思ったのでnetモジュールでサーバを立てて、telnet経由でコマンドを叩くと制御できるようにしたりもしました。
環境:Ubuntu 12.04 LTS 64bit / node.js 0.8.9

master.js
#!/usr/bin/env node

var cluster = require('cluster'),
    net = require('net'),
    path = require('path'),
    server = net.createServer(),
    clusters = [];

server.on('connection', function (socket) {
  socket.setEncoding('utf8');

  socket.on('connect', function () {
    socket.write('connect.\n');
    socket.write('> ');
  });

  socket.on('data', function (buffer) {
    var i = 0,
        len = clusters.length;

    switch (buffer.replace(/\r?\n$/, '')) {
      case 'close':
        socket.end();
        server.close();
        break;
      case 'fork':
        clusters.push(
          cluster.fork({ id: clusters.length }));
        break;
      case 'killall':
        for (; i < len; ++i) {
          clusters[i].destroy();
        }
        clusters = [];
        break;
      case 'quit':
        socket.end();
        break;
    }
    socket.write('> ');
  });
});

server.on('error', function (err) {
  console.error('server error: ' + err);
});

process.on('SIGINT', function () {
  cluster.disconnect(function () {
    console.log('worker disconnected.');
    console.log('process exit.');
    process.exit();
  });
});

cluster.setupMaster({
  exec: path.join(__dirname, 'worker.js')
});

cluster.on('death', function (worker) {
  console.log('worker %d died.', worker.pid);
});

server.listen(3000);
worker.js
#!/usr/bin/env node

setInterval(function () {
  console.log('worker %d: interval', process.env.id);
}, 1000);


上記のファイルを2つ同じディレクトリに配置したら以下のコマンドで実行します。

$ node master.js

今度は別の端末から以下を実行します。

$ telnet localhost 3000


すると

connect.
> 

となるのでforkと入力してEnterを押してみると……

> fork

node.jsを実行した方のサーバに

worker 0: interval
worker 0: interval
worker 0: interval

が一秒起きに表示されます。
何度もforkをすると

> fork
> fork
worker 0: interval
worker 1: interval
worker 0: interval
worker 2: interval
worker 0: interval
worker 1: interval
worker 2: interval

というような表示がされます。


表示を止めたくなったら

> killall

で停止します。


あとはcloseでサーバを止めたり、quitで接続を切ったりなどができたりします。
telnetでつないでコマンドを叩く的なことができてなかなか面白いので応用をきかせるともっと楽しいのかもしれません。