non vorrei lavorare

ブログ名の通りです。javascript three.js mruby rust OCaml golang julialang blender

ファイルの監視は難しいことをviに教えてもらった

先日、とある記事がバズって、長男と一緒に、Google Analyticsのリアルタイムに表示されるアクセス数を見ていたら、数字が切り替わる度に、長男に数字を尋ねると、ほぼ正答しており、長男は数字がほぼ読める様になってきたようです。kjunichiです。

20150228subimage

設定ファイルが変更されたらリロードしたい

去年の記事「Castoを知りkqueueにたどり着いた件」でOSXならばkqueueを使うのが、エコなんだろうということが分かっていたので、libeventの2.0系からはWindowsにも対応しているし、もちろんLinuxのepollにも対応しているから、これでいいかなぁということで、始めはlibeventでやってみた。

libeventを試す

1.0系のAPIを使ったサンプルが動いた

に素晴らしいサンプルがあり、幸いにも

gcc `pkg-config libevent --cflags --libs` main.c -o fileupdchk

と、HomebrewでもlibeventはOpenSSLとは違い、keg-onlyなライブラリでは無いので、pkg-configが利用可能で、簡単にビルドして動かせた。

たしかにtailは動いた

touch foo
./fileupdchk foo 

と動かし、別の端末から

echo "hoge">>foo

とすれば、fooの文字列が表示される。

ファイルの変更から雲行きが怪しく

Atom.ioエディタで編集すると、closeが大量に表示され、打ち込んでない文字が表示される。

この現象は、readで読み込むfdは前回readした直後からだから、適当にseekすればOKな気がする。

viで問題発生

普段は、出先ではviオンリーだが、今回は自宅でAtom.ioが使える環境だから、使うことはあまりないのだが、たまたま動かした。すると、更新する検出されない!

調べながら、なんとなくviは直接ファイルの編集をしていないんだったような事をおぼろげに思い出しつつ、以下の記事を見つけた。

vi(もしかするとvim)は、直接指定したファイルを更新するということをしない。作業用ファイルを一時的に作成し、これを更新して、その後、本来のファイルに置き換えるという事をしている。

この為、編集対象のfdを監視していても検知出来ないのだった。

libeventだと難しそう

今回やりたい、設定ファイルの更新はバリバリviで編集される可能性が高いし、自分も外出先では確実のそうするので、対応が必須。

どうもlibeventは通信向けのライブラリの性格が強いので、こういった対象ファイルの削除には対応していないんではないか?と思い始めた。

ファイル監視向けのライブラリを探す

OSX向けにRubyではrb-fseventなるOSXでファイル監視のネイティブAPIらしいFSEventsを内部で使っているGemがあり、これが、Rubyの2.2.0でも動いた。

Linuxだとmrubyのmruby-inotifyが見つかった。

まとめ

設定ファイルのvi編集に対応するには、ファイルそのものの監視に加え、対象ファイルが削除された時点からはディレクトリも監視対象にする必要がある。

Atom.ioはこの辺りもうまいことやっている事にふと気が付き、FSEventsを直接は使っていないことは分かったが、Chromium側でやってるのかio.js側なのかは分からなかった。