class Build::Files::Monitor::Polling
def add(handle)
def add(handle) @logger.debug{"Adding handle: #{handle}"} handle.directories.each do |directory| # We want the full path as a plain string: directory = directory.to_s @directories[directory] << handle # We just added the first handle: if @directories[directory].size == 1 # If the handle already existed, this might trigger unnecessarily. @updated = true end end handle end
def delay_deletions
def delay_deletions @deletions = [] yield @deletions.each do |handle| purge(handle) end @deletions = nil end
def delete(handle)
def delete(handle) if @deletions @logger.debug{"Delayed delete handle: #{handle}"} @deletions << handle else purge(handle) end end
def initialize(logger: nil)
def initialize(logger: nil) @directories = Hash.new do |hash, key| hash[key] = Set.new end @updated = false @deletions = nil @logger = logger || Logger.new(nil) end
def purge(handle)
def purge(handle) @logger.debug{"Purge handle: #{handle}"} handle.directories.each do |directory| directory = directory.to_s @directories[directory].delete(handle) # Remove the entire record if there are no handles: if @directories[directory].size == 0 @directories.delete(directory) @updated = true end end end
def roots
def roots @directories.keys end
def run(**options, &block)
def run(**options, &block) catch(:interrupt) do while true monitor.update(monitor.roots) yield sleep(options[:latency] || 1.0) end end end
def track_changes(files, &block)
def track_changes(files, &block) handle = Handle.new(self, files, &block) add(handle) end
def update(directories, *args)
def update(directories, *args) @logger.debug{"Update: #{directories} #{args.inspect}"} delay_deletions do directories.each do |directory| @logger.debug{"Directory: #{directory}"} @directories[directory].each do |handle| @logger.debug{"Handle changed: #{handle.inspect}"} # Changes here may not actually require an update to the handle: handle.changed!(*args) end end end end