Watch a directory or file for events like create, modify, delete, etc. (See Sinotify::Event for full list).
See the synopsis section in the README.txt for example usage.
Methods
public class
public instance
Included modules
- Cosell
Attributes
| etypes | [RW] | |
| file_or_dir_name | [RW] | |
| logger | [RW] | |
| recurse | [RW] | |
| recurse_throttle | [RW] |
Public class methods
Required Args
file_or_dir_name: the file/directory to watch
Options:
:recurse => (true|false) whether to automatically create watches on sub directories default: true if file_or_dir_name is a directory, else false raises if true and file_or_dir_name is not a directory :recurse_throttle => When recursing, a background thread drills down into all the child directories creating notifiers on them. The recurse_throttle tells the notifier how far to recurse before sleeping for 0.1 seconds, so that drilling down does not hog the system on large directorie hierarchies. default is 10 :etypes => which inotify file system event types to listen for (eg :create, :delete, etc) See docs for Sinotify::Event for list of event types. default is [:create, :modify, :delete] Use :all_events to trace everything (although this may be more than you bargained for). :logger => Where to log errors to. Default is Logger.new(STDOUT). :announcement_throttle => How many events can be announced at a time before the queue goes back to sleep for a cycle. (ie. Cosell's 'announcements_per_cycle') :announcements_sleep_time => How long the queue should sleep for before announcing the next batch of queued up Sinotify::Events (ie. Cosell's 'sleep_time')
# File lib/sinotify/notifier.rb, line 49 def initialize(file_or_dir_name, opts = {}) initialize_cosell! # init the announcements framework raise "Could not find #{file_or_dir_name}" unless File.exist?(file_or_dir_name) self.file_or_dir_name = file_or_dir_name # by default, recurse if directory?. If opts[:recurse] was true and passed in, # make sure the watch is on a directory self.recurse = opts[:recurse].nil?? self.on_directory? : opts[:recurse] raise "Cannot recurse, #{file_or_dir_name} is not a directory" if self.recurse? && !self.on_directory? # how many directories at a time to register. self.recurse_throttle = opts[:recurse_throttle] || 10 self.etypes = Array( opts[:etypes] || [:create, :modify, :delete] ) validate_etypes! self.prim_notifier = Sinotify::PrimNotifier.new # setup async announcements queue (part of the Cosell mixin) @logger = opts[:logger] || Logger.new(STDOUT) sleep_time = opts[:announcements_sleep_time] || 0.05 announcement_throttle = opts[:announcement_throttle] || 50 self.queue_announcements!(:sleep_time => sleep_time, :logger => @logger, :announcements_per_cycle => announcement_throttle) self.closed = false # initialize a few variables just to shut up the ruby warnings # Apparently the lazy init idiom using ||= is no longer approved of. Shame that. @spy_logger = nil @spy_logger_level = nil @watch_thread = nil end
Public instance methods
Return a list of files/directories currently being watched. Will only contain one entry unless this notifier was setup on a directory with the option :recurse => true.
# File lib/sinotify/notifier.rb, line 143 def all_directories_being_watched self.watches.values.collect{|w| w.path }.sort end
Close this notifier. Notifiers cannot be reopened after close!.
# File lib/sinotify/notifier.rb, line 118 def close! @closed = true self.remove_all_watches end
whether this watch is on a directory
# File lib/sinotify/notifier.rb, line 105 def on_directory? File.directory?(self.file_or_dir_name) end
Sugar.
Equivalent of calling cosell’s
self.when_announcing(Sinotify::Event) do |event| do_something_with_event(event) end
becomes
self.on_event { |event| do_something_with_event(event) }
Since this class only announces one kind of event, it made sense to provide a more terse version of that statement.
# File lib/sinotify/notifier.rb, line 100 def on_event &block self.when_announcing(Sinotify::Event, &block) end
Whether this notifier watches all the files in all of the subdirectories of the directory being watched.
# File lib/sinotify/notifier.rb, line 153 def recurse? self.recurse end
Log a message every time a prim_event comes in (will be logged even if it is considered ‘noise’), and log a message whenever an event is announced. Overrides Cosell’s spy! method (and uses cosell’s spy! to log announced events).
Options:
:logger => The log to log to. Default is a logger on STDOUT :level => The log level to log with. Default is :info :spy_on_prim_events => Spy on PrimEvents (raw inotify events) too
# File lib/sinotify/notifier.rb, line 132 def spy!(opts = {}) self.spy_on_prim_events = opts[:spy_on_prim_events].eql?(true) self.spy_logger = opts[:logger] || Logger.new(STDOUT) self.spy_logger_level = opts[:level] || :info opts[:on] = Sinotify::Event opts[:preface_with] = "Sinotify::Notifier Event Spy" super(opts) end
# File lib/sinotify/notifier.rb, line 157 def to_s "Sinotify::Notifier[#{self.file_or_dir_name}, :watches => #{self.watches.size}]" end
Start watching for inotify file system events.
# File lib/sinotify/notifier.rb, line 110 def watch! raise "Cannot reopen an inotifier. Create a new one instead" if self.closed? self.add_all_directories_in_background self.start_prim_event_loop_thread return self end