Module: Mbeditor::FileWatcher
- Defined in:
- lib/mbeditor/file_watcher.rb
Overview
Watches the workspace for changes made outside the editor — a terminal
git checkout, a rebase, another editor, a generator — and broadcasts the
same files_changed payload the mutation endpoints send. Clients refresh
the file tree, git line-number tinting and cached globals from it.
The listen gem is an optional host dependency. Without it the editor
behaves exactly as before: only changes made through mbeditor announce
themselves. Nothing warns loudly about the missing gem — it is opt-in.
Only one watcher runs per process. It is deliberately not started in test or in non-server processes (rake, console, the Rails runner), where a background listener thread is pure overhead.
Constant Summary collapse
- DEBOUNCE_SECONDS =
Coalesce bursts: a branch switch touches hundreds of files, and each one would otherwise be its own broadcast.
0.3
Class Method Summary collapse
- .available? ⇒ Boolean
- .running? ⇒ Boolean
-
.start(root) ⇒ Object
Returns true when a watcher was started, false for every reason not to (gem absent, already running, no workspace, disabled by config).
-
.start_if_enabled ⇒ Object
Boot entry point.
- .stop ⇒ Object
Class Method Details
.available? ⇒ Boolean
22 23 24 25 26 27 28 29 30 31 |
# File 'lib/mbeditor/file_watcher.rb', line 22 def available? return @available if defined?(@available) @available = begin require "listen" true rescue LoadError false end end |
.running? ⇒ Boolean
33 34 35 |
# File 'lib/mbeditor/file_watcher.rb', line 33 def running? !@listener.nil? end |
.start(root) ⇒ Object
Returns true when a watcher was started, false for every reason not to (gem absent, already running, no workspace, disabled by config).
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/mbeditor/file_watcher.rb', line 53 def start(root) return false unless available? return false if running? root = root.to_s return false if root.empty? || !File.directory?(root) ignores = ignore_patterns(root) @listener = ::Listen.to(root, ignore: ignores, latency: DEBOUNCE_SECONDS) do |modified, added, removed| broadcast(root, modified + added + removed) end @listener.start Rails.logger.info("[mbeditor] watching #{root} for external changes") true rescue StandardError => e # A watcher that cannot start must never take the host app down with it: # inotify limits on Linux, permission issues, an unreadable root. Rails.logger.warn("[mbeditor] file watcher failed to start: #{e.class}: #{e.}") @listener = nil false end |
.start_if_enabled ⇒ Object
Boot entry point. Confined to the environments the editor is allowed in and to processes that actually serve requests — a rake task or console has no client to broadcast to, and a listener thread there would only burn file handles. MBEDITOR_FORCE_WATCH overrides the process check for unusual servers and for tests.
42 43 44 45 46 47 48 49 |
# File 'lib/mbeditor/file_watcher.rb', line 42 def start_if_enabled cfg = Mbeditor.configuration return false if cfg.watch_files == false return false unless cfg.allowed_environments.map(&:to_s).include?(Rails.env.to_s) return false unless serving_requests? start(cfg.workspace_root.presence || Rails.root.to_s) end |
.stop ⇒ Object
75 76 77 78 79 80 81 |
# File 'lib/mbeditor/file_watcher.rb', line 75 def stop @listener&.stop rescue StandardError nil ensure @listener = nil end |