hagino3000's blog

平成アーカイブス (更新停止)

Chromeでworkerプロセスが死ぬ問題

解決するのにここ2日間かかってしまったバグ。
WebWorkerでworkerプロセスを作る。workerの中でタイマーを回して5分毎にサーバーからデータを取得、そのデータをメインスレッドに返す、というのを実装したが、workerが5分~10分経つと死んでいるというもの。onerrorへの通知も無い。
いろいろ悩んだ末、もしかしてGCされてるんじゃあ……と思ったらその通りのようで、グローバルオブジェクトから参照できる所に突っこんでおいたら死ななくなった。

Operaだと動いているworkerが勝手に殺されたりしないのでChromeのバグかも*1GCしてくれなくてもworkerを殺す手段としてterminateメソッドが用意されている。自分で作成したworkerは自分で殺した方がわかりやすい。

検証ページ(workerを2つ作って、片方のみglobalオブジェクトから参照可能にしておく)
http://hagino3k.appspot.com/sample/worker/index.html

コード

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script>
(function init() {
  var workerA = new Worker('worker.js');
  workerA.onmessage = function(event) {
    console.info('Receive message from A:' +new Date());
  };
  workerA.postMessage('ping');

  var workerB = new Worker('worker.js');
  workerB.onmessage = function(event) {
    console.info('Receive message from B:' +new Date());
  };
  workerB.postMessage('ping');

  // Add a reference to the global object
  window.workerB = workerB;
})();
</script>
<title>Web Workers test</title>
</head>
<body>
<div id="output">Check console for info messages</div>
</body>
</html>
// worker.js
onmessage = function(e) {
  setInterval(ping, 1000*5);
}

function ping() {
  postMessage('ping');
}

*1:issueが登録されたので修正されるかも。 http://code.google.com/p/chromium/issues/detail?id=47379