class Core::Watch::System
- public
-
The system watcher.
Attributes
interval[RW]
- public
-
The configured polling interval.
latency[R]
- public
-
The current latency.
status[R]
- public
-
The status object.
Public Class Methods
new(interval: 0.1, strategy: :digest)
click to toggle source
# File lib/core/watch/system.rb, line 33 def initialize(interval: 0.1, strategy: :digest) @interval = interval @status = Status.new @mutex = Mutex.new @watched = [] @ignored = [] @callbacks = [] @working = false @latency = nil @strategy = case strategy.to_sym when :digest require_relative "strategies/digest" Strategies::Digest when :timestamp require_relative "strategies/timestamp" Strategies::Timestamp else raise ArgumentError, "unknown watch strategy `#{strategy.inspect}'" end end
Public Instance Methods
callback(matcher = nil, &block)
click to toggle source
- public
-
Register a callback to be called when a change is detected. The callback will only be called once per
tick and will be given a `Core::Watch::Diff` instance. If `matcher` is passed, the callback will only be called for matching changes. The matcher can be a string or any object that responds to `match?`.
# File lib/core/watch/system.rb, line 87 def callback(matcher = nil, &block) raise ArgumentError, "expected a block" if block.nil? @mutex.synchronize do @callbacks << Callback.build(matcher, &block) end end
ignore(path)
click to toggle source
- public
-
Ignore changes at `path`.
# File lib/core/watch/system.rb, line 71 def ignore(path) path = path.to_s @mutex.synchronize do unless @ignored.include?(path) mutate do @ignored << path end end end end
pause()
click to toggle source
- public
-
Pause the watcher, causing it to continue running but not invoke callbacks.
# File lib/core/watch/system.rb, line 117 def pause @status.paused! end
resume()
click to toggle source
- public
-
Resume a paused watcher.
# File lib/core/watch/system.rb, line 123 def resume @status.running! end
start()
click to toggle source
- public
-
Start the watcher.
# File lib/core/watch/system.rb, line 97 def start await do unless @status.running? @future = run end end end
stop(force: false)
click to toggle source
- public
-
Stop the watcher.
# File lib/core/watch/system.rb, line 107 def stop(force: false) if !@working || force @future&.cancel end @status.stopped! end
watch(path)
click to toggle source
- public
-
Watch
`path` for changes.
# File lib/core/watch/system.rb, line 57 def watch(path) path = Pathname(path).expand_path @mutex.synchronize do unless @watched.include?(path) mutate do @watched << path end end end end
Private Instance Methods
current_time()
click to toggle source
# File lib/core/watch/system.rb, line 186 def current_time Process.clock_gettime(Process::CLOCK_MONOTONIC) end
invoke_callbacks(diff)
click to toggle source
# File lib/core/watch/system.rb, line 165 def invoke_callbacks(diff) return unless diff.changed? await do @working = true @callbacks.each do |callback| maybe_invoke_callback(callback, diff) end end ensure @working = false end
maybe_invoke_callback(callback, diff)
click to toggle source
# File lib/core/watch/system.rb, line 178 def maybe_invoke_callback(callback, diff) diff.each_change do |path, event| if callback.match?(path) return async { callback.call(diff) } end end end
mutate() { || ... }
click to toggle source
# File lib/core/watch/system.rb, line 153 def mutate yield if @status.running? rebuild_snapshot end end
rebuild_snapshot()
click to toggle source
# File lib/core/watch/system.rb, line 161 def rebuild_snapshot @snapshot = Snapshot.new(*@watched, ignore: @ignored, strategy: @strategy) end
run()
click to toggle source
# File lib/core/watch/system.rb, line 127 def run async { @status.running! rebuild_snapshot until @status.stopped? sleep(@interval) started = current_time # Don't process this tick if the watch was paused or stopped while sleeping. # next if @status.paused? || @status.stopped? # Do the work, updating the snapshot in the process. # invoke_callbacks(@snapshot.diff) # Measure the latency for this tick. # @latency = [0, current_time - started - @interval].max end } end