spring-watcher-listen

参考:

jonleighton/spring-watcher-listen – GitHub

ドキュメント

参考:

Documentation for spring | RubyDoc.info

Documentation for spring-watcher-listen | RubyDoc.info

Spring.watch / watcher.add

デフォルトで追加されるパス

  • loaded_application_features
  • Gemfile
  • Gemfile.lock
  • config/initializers
  • config/database
  • config/secrets

config/spring.rb で監視するファイル・ディレクトリを追加する。

%w[
  .ruby-version
  .rbenv-vars
  tmp/restart.txt
  tmp/caching-dev.txt
].each { |path| Spring.watch(path) }

監視されているファイルを確認する。

$ rails console
> puts Spring.watcher.files.grep %r{/my_project/config/}
/path/to/my_project/config/spring.rb
/path/to/my_project/config/boot.rb
/path/to/my_project/config/application.rb
...

監視されているディレクトリを確認する。

$ rails console
> puts Spring.watcher.directories.to_a
/path/to/my_project/config/initializers
/path/to/my_project/config

参考:

Method: Spring.watch — Documentation for spring | RubyDoc.info

Method: Spring.watcher — Documentation for spring | RubyDoc.info

Method: Spring::Watcher::Abstract#add — Documentation for spring | RubyDoc.info

Watching files and directories – rails/spring: Rails application preloader – GitHub

watcher.add – spring/application.rb at v2.1.0 · rails/spring – GitHub

loaded_application_features – spring/application.rb at v2.1.0 · rails/spring – GitHub

Spring.watcher – spring/watcher.rb at v2.1.0 · rails/spring – GitHub

Spring.watch – spring/watcher.rb at v2.1.0 · rails/spring – GitHub

ファイルの監視とキャッシュのクリア

Spring 経由で実行される rails コマンドでファイルの変更が反映されない場合は、Spring サーバーを再起動する必要がある。

$ spring stop

もしくは、config/spring.rb で監視するファイル・ディレクトリの対象として追加する。

参考:

Rails5 で app 以下のディレクトリが読み込まれないとき | nyarn.tech

Rails で app 以下の変更を Spring が検知しない問題を解決した(?) | マスタカの ChangeLog メモ

symlink が含まれていた場合に表示されるエラーについて

監視するファイル/ディレクトリに symlink が含まれていた場合にエラーが表示される。

エラーをどうにかしたい場合は、以下のモンキーパッチを活用する。

エラーの表示を抑制するモンキーパッチ

module ListenSymlinkErrorSilencer
  def _fail(_, _)
    fail(
      Listen::Record::SymlinkDetector::Error,
      "Don't watch locally-symlinked directory twice"
    )
  end
end

Listen::Record::SymlinkDetector.prepend(
  ListenSymlinkErrorSilencer
)

監視するディレクトリを変更するパッチ

プロジェクトのルートディレクトリを監視に含めずに、ルートディレクトリ下の symlink ではないディレクトリを監視に含める。(起動が遅くなる可能性がある。※ 非推奨)

module ListenBaseDirectoriesExtension
  def base_directories
    ((Dir.children(root)
      .select { |entry| File.directory? File.join(root, entry) }
      .reject { |entry| File.symlink?   File.join(root, entry) }
      .map { |d| File.expand_path(d) } +
      files.map { |f| File.expand_path("#{f}/..") } +
      directories.to_a
    ).uniq - [root])
    .map { |path| Pathname.new(path) }
  end
end

Spring::Watcher::Listen.prepend(
  ListenBaseDirectoriesExtension
)

参考:

Duplicate directory errors · guard/listen Wiki – GitHub

abort on filesystem loop by e2 · Pull Request #273 · guard/listen – GitHub

Feature request: Listen could *really ignore* ignored directories (optimization) · Issue #274 · guard/listen

Suppress errors on local symlinks · Issue #339 · guard/listen – GitHub

Using Listen on Rails root spams errors on local symlinks · Issue #8 · jonleighton/spring-watcher-listen – GitHub

listen/symlink_detector.rb at v3.1.5 · guard/listen – GitHub

spring-watcher-listen/listen.rb at v2.0.1 · jonleighton/spring-watcher-listen – GitHub

add – spring/abstract.rb at v2.0.2 · rails/spring

symlink を辿らない

監視対象ディレクトリ内に symlink が含まれていても辿らない。Listen の仕様。

参考:

Listener does not follow symlinks · Issue #25 · guard/listen – GitHub

Support for symlinked directories · Issue #19 · thibaudgg/rb-fsevent – GitHub

ignore

Listen における ignore の設定は、イベント発生後に除外されるのでイベントが発生しなくなるわけではない。ignore の設定によって監視イベントの負荷を下げることはできない。

参考:

Some way to ignore files on Rails 5… · Issue #15 · jonleighton/spring-watcher-listen – GitHub

ignore – listen/listener.rb at v3.1.5 · guard/listen – GitHub

append_ignores – listen/controller.rb at v3.1.5 · guard/listen – GitHub

ignore – listen/silencer.rb at v3.1.5 · guard/listen – GitHub

I18n の翻訳ファイルがリロードされない

翻訳ファイルの変更を反映させるためには Spring サーバーの再起動が必要である。

$ spring stop

自動的に再起動させるためには、config/spring.rb で翻訳ファイルもしくはディレクトリを監視対象に追加する。

参考:

新しく国際化ファイルを追加した時は spring を再起動してやらないと rails console に反映されない – Qiita

New locale files require a Spring restart | makandra dev

require した gem をリロードする

コンソールから reload! で gem の定数を再読み込みできるようにする。

config/environments/development.rb で全てのローカル gem を再読み込み可能にする。

RequireReloader.watch_local_gems!

指定した gem を再読み込み可能にする。

RequireReloader.watch :my_gem

参考:

ローカルで開発中の gem をリロードする – Qiita

teohm/require_reloader: Auto-reload require files or local gems without restarting server in Rails development – GitHub

fsevent_watch プロセスが大量に生成される

基本的には Spring サーバーを止めれば fsevent_watch プロセスは終了する。

$ spring stop

それでも残っているプロセスは kill してしまってよい。

$ killall fsevent_watch

参考:

fsevent_watch bomb on OSX. · Issue #513 · rails/spring – GitHub

The listen gem breaks my laptop · Issue #26158 · rails/rails – GitHub

Too many orphaned processes on OSX in Rails · Issue #412 · guard/listen – GitHub

Why is there many instances of “fsevent_watch” under Ruby in mac? – Stack Overflow

Spring::Watcher::Listen

参考:

spring-watcher-listen/listen.rb at v2.0.1 · jonleighton/spring-watcher-listen – GitHub

start_watcher

アプリケーションでファイルの監視をスタートさせる。

参考:

start_watcher – spring/application.rb at v2.1.0 · rails/spring – GitHub

add

指定されたファイル/ディレクトリを監視対象として追加する。

参考:

add – spring/abstract.rb at v2.1.0 · rails/spring – GitHub

Listen

参考:

listen/listen.rb at v3.1.5 · guard/listen – GitHub

Listen::Listener

参考:

listen/listener.rb at v3.1.5 · guard/listen – GitHub

Listen::Listener::Config

参考:

listen/config.rb at v3.1.5 · guard/listen – GitHub

Listen::Silencer

参考:

listen/silencer.rb at v3.1.5 · guard/listen – GitHub

Listen::Record::SymlinkDetector

symlink による循環参照を検出してエラーメッセージを出力する。

ERROR: directory is already being watched!

参考:

listen/symlink_detector.rb at v3.1.5 · guard/listen – GitHub

rb-fsevent

参考:

Why is rb-fsevent taking up over 100% CPU? – Stack Overflow

renice

参考:

Throttle Down Rails Processes | Better Every Day

OS X: throttle application CPU utilization | tinyapps.org

記事をシェアする:
タグ:

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

Protected by reCAPTCHA