やっと負荷問題が解決しましたよ〜
前回上記記事で、node_modulesフォルダが有る場合のgoapp serve問題について書きました。
今回はその記事の続きとなります。
おさらい
一応おさらいしておきます。
GAE/Golangアプリケーションを起動するコマンドに「goapp serve」というものがあります。これを実行するとGAEアプリケーションが起動します。
しかし、昨今npmモジュールとwebpackやbrowserifyを使ってjsでウェイウェイする開発が一般的ですね。goapp serveは、npmのwatchのようにファイルの変更を監視してホットデプロイする機能があります。このファイル監視がnode_modulesフォルダ内まで観てしまい、監視ファイル数オーバーを引き起こしてしまっていました。
冒頭の記事で、とりあえずnode_modulesでエラーがでないようにし、とりあえずgoapp serveで起動する事はできました。しかし実は完全に解決していませんでした。
実は問題が有った
あのやり方ではnode_modulesのエラーが出ないだけで、監視自体はガッツリ行われているっぽかったのです。その証拠として、npm installするとgoapp serveがnpmモジュール追加に逐一反応している(エラーにはならない)し、CPUのコアを1つ使いきるくらいの負荷(CPU使用率的には50%オーバー)で、結構酷い状態なのでした。
今回はnode_modulesの監視を完全に止める方法がようやく解ったので、書いてみます。
修正方法
goランタイム
go_appengineのバージョンによって変更するファイルパスが違うようです。今回は v1.9.48 の修正方法となります。
$ goapp version go version go1.6.3 (appengine-1.9.48) darwin/amd64
変更するファイル
修正するのは以下のファイルです。
${GO_APPENGINE}/google/appengine/tools/devappserver2/watcher_common.py
ネットで調べてみると、go_appengineのバージョンによって watcher_common.py のパスが違うようなので、見つからない場合はfind等で自分で探してみて下さい。
修正内容
変更前
def ignore_dir(dirpath, dirname, skip_files_re): """Report whether a directory should not be watched.""" return (dirname.startswith(_IGNORED_PREFIX) or skip_files_re and skip_files_re.match(os.path.join(dirpath, dirname)))
変更後
_IGNORED_DIRS = ('node_modules',) def ignore_dir(dirpath, dirname, skip_files_re): """Report whether a directory should not be watched.""" return (dirname.startswith(_IGNORED_PREFIX) or skip_files_re and skip_files_re.match(os.path.join(dirpath, dirname)) or dirname in _IGNORED_DIRS)
これで、node_modulesの監視自体をしないようになり、且つ、goapp serveした際の「There are too many files」も起きなくなり、一件落着となります。
雑感
バージョンアップ毎に手動でgo_appengineのモジュールを手動で修正する事になるので、正直嫌ですね・・・
環境変数で_IGNORED_DIRSが設定できれば凄く楽なんですけどね。
という事で、ちょっと面倒臭いとはいえこれで夜中CPUがブン回って暑くて起こされたりしなくなりますので、皆さんも夏に備えてnode_modulesの監視回避はして下さいね!