ノビコード.md

blogその2。markdownで書きたくなりました。

fs.watchFileを使ってみた

fs.watchfileとは?

 ファイルの変更を監視して、変化が起きたらcallback関数を呼び出して教えてくれる。node以外では見たことない気がするのは、不勉強かしら。

 とにかく、そういうファイルの変更を検知するやつを作りたかったので、こまかい動きを調べてメモしました。

実験に使ったコード

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var fs = require('fs');

var filepath = 'message.txt';

// filepathが存在しなくても、watchFileはエラーとか出してくれないので、
// 先にfs.existsで調べておく
if (!fs.existsSync(filepath)) {
  console.error('%s doesn\'t exist.', filepath);
  process.exit();
}

console.log('start watch: %s', filepath);
fs.watchFile(filepath, function (curr, prev) {
  // プロパティ丸ごと出力してもらう
  console.dir(curr);

  // 以前のmtimeと比較
  console.log('the current mtime is: ' + curr.mtime);
  console.log('the previous mtime was: ' + prev.mtime);
});

分かったこと

開始時に、指定したfilepathが存在しなくても、特にエラーは発生しない。

  • なので、その前に自分でfs.existsとかしてあげる必要がある。(上のコード参照)

ファイル名を変更しても、ファイルの変更とはみなされない。

  • ただし、ファイル名を変更した後も、監視は続いている。
  • chmodとかは、ちゃんと変更とみなされる。

callbackに帰ってくるのはstatオブジェクト。

  • なので、更新時間や属性などは即時でとれるが、ファイルの内容がどうなったかは、別途fs.readFileなどしないと分からない。
  • diff的な機能もなし。

対象がディレクトリでもちゃんと動く。

  • ディレクトリの中のファイルが変更された時、中にファイルが追加された時等ちゃんと検知します。
  • viで中身のファイル開いた時に、一時ファイルができるのも検知してしまうので、ちょっととまどった。(そりゃそうなんだけど)

当然、「常時待ち」のイベントをひとつ増やすことになる。

  • 例えばexpressサーバーとかは、平常時はhttpサーバーへのアクセスのみ待っている状態になっている。そこに別の常時待ちが入ってくると、なにかしら計算が狂うこともありうる。
  • 自分は、start-stop-daemonとexpressを組み合わせて使っていたので、daemon化する部分にwatchFileの開始処理も組込んでやる必要があった。

そのうち調べる

  • 監視周期1回の間に、変更が2回以上発生したら? (たぶん1回しか反応しないと思うけど)
  • 存在しないファイル名を与えてwatchを開始、その後そのファイルが追加されたら? (たぶん反応しないと思うけど)
  • unwatchも調べなきゃ……。

Rdfstore-jsを使うときの注意

 主にエラーハンドリングの処理で、イケてない部分が見つかったのでメモ。

rdfstore-js

パッケージ

実行環境

  • node (v0.8.16)
  • rdfstore (v0.7.0)

store.executeについて

 callback(success, result)の形にはなっているが、実際にはSyntaxErrorが起きた時にはcallbackしないでエラー終了してしまう。

 現状では、executeしている部分をまるごとtry-catchで囲むか、rdfstore側のコードを修正するしかない。

 SyntaxError時に直接エラーをはいているのは、L22804のthrow。(ここをthrowじゃなくてreturnにすればうまく使える?)

store.loadについて

 ファイルのロードに失敗した場合(たぶん厳密に言うと、指定したContentTypeでファイルが読めなかった場合)、L5294とL5295のconsole.logは、自分の環境ではいつもundefinedを返してきた。

 動作上は問題無いけれど、ログに邪魔なものが残るので、削っていいと思う。