Upgrade FSSM.

This commit is contained in:
Chris Eppstein 2010-01-18 17:11:06 -08:00
parent 68fe3136c2
commit b0fbab5455
10 changed files with 117 additions and 92 deletions

View File

@ -12,15 +12,7 @@ module FSSM
def monitor(*args, &block) def monitor(*args, &block)
monitor = FSSM::Monitor.new monitor = FSSM::Monitor.new
context = args.empty? ? monitor : monitor.path(*args) FSSM::Support.use_block(args.empty? ? monitor : monitor.path(*args), block)
if block_given?
if block.arity == 1
block.call(context)
else
context.instance_eval(&block)
end
end
monitor.run monitor.run
end end
@ -33,7 +25,8 @@ require 'fssm/pathname'
require 'fssm/support' require 'fssm/support'
require 'fssm/tree' require 'fssm/tree'
require 'fssm/path' require 'fssm/path'
require 'fssm/state' require 'fssm/state/directory'
require 'fssm/state/file'
require 'fssm/monitor' require 'fssm/monitor'
require "fssm/backends/#{FSSM::Support.backend.downcase}" require "fssm/backends/#{FSSM::Support.backend.downcase}"

View File

@ -7,18 +7,17 @@ module FSSM::Backends
@fsevents = [] @fsevents = []
end end
def add_path(path, preload=true) def add_handler(handler, preload=true)
handler = FSSM::State.new(path) @handlers[handler.path.to_s] = handler
@handlers["#{path}"] = handler
fsevent = Rucola::FSEvents.new("#{path}", {:latency => 0.5}) do |events| fsevent = Rucola::FSEvents.new(handler.path.to_s, {:latency => 0.5}) do |events|
events.each do |event| events.each do |event|
handler.refresh(event.path) handler.refresh(event.path)
end end
end end
fsevent.create_stream fsevent.create_stream
handler.refresh(path.to_pathname, true) if preload handler.refresh(nil, true) if preload
fsevent.start fsevent.start
@fsevents << fsevent @fsevents << fsevent
end end

View File

@ -4,14 +4,12 @@ module FSSM::Backends
@notifier = INotify::Notifier.new @notifier = INotify::Notifier.new
end end
def add_path(path, preload=true) def add_handler(handler, preload=true)
handler = FSSM::State.new(path) @notifier.watch(handler.path.to_s, :all_events) do |event|
@notifier.watch(path.to_s, :all_events) do |event|
handler.refresh(event.name) handler.refresh(event.name)
end end
handler.refresh(path.to_pathname, true) if preload handler.refresh(nil, true) if preload
end end
def run def run

View File

@ -5,9 +5,8 @@ module FSSM::Backends
@latency = options[:latency] || 1.5 @latency = options[:latency] || 1.5
end end
def add_path(path, preload=true) def add_handler(handler, preload=true)
handler = FSSM::State.new(path) handler.refresh(nil, true) if preload
handler.refresh(path.to_pathname, true) if preload
@handlers << handler @handlers << handler
end end

View File

@ -6,16 +6,17 @@ class FSSM::Monitor
def path(*args, &block) def path(*args, &block)
path = FSSM::Path.new(*args) path = FSSM::Path.new(*args)
FSSM::Support.use_block(path, block)
if block_given? @backend.add_handler(FSSM::State::Directory.new(path))
if block.arity == 1 path
block.call(path) end
else
path.instance_eval(&block)
end
end
@backend.add_path(path) def file(*args, &block)
path = FSSM::Path.new(*args)
FSSM::Support.use_block(path, block)
@backend.add_handler(FSSM::State::File.new(path))
path path
end end

View File

@ -81,7 +81,7 @@ class FSSM::Path
def set_path(path) def set_path(path)
path = FSSM::Pathname.for(path) path = FSSM::Pathname.for(path)
raise FSSM::FileNotFoundError, "#{path}" unless path.exist? raise FSSM::FileNotFoundError, "No such file or directory - #{path}" unless path.exist?
@path = path.expand_path @path = path.expand_path
end end

View File

@ -1,54 +0,0 @@
require 'yaml'
class FSSM::State
def initialize(path)
@path = path
@cache = FSSM::Tree::Cache.new
end
def refresh(base=nil, skip_callbacks=false)
previous, current = recache(base || @path.to_pathname)
unless skip_callbacks
deleted(previous, current)
created(previous, current)
modified(previous, current)
end
end
private
def created(previous, current)
(current.keys - previous.keys).each {|created| @path.create(created)}
end
def deleted(previous, current)
(previous.keys - current.keys).each {|deleted| @path.delete(deleted)}
end
def modified(previous, current)
(current.keys & previous.keys).each do |file|
@path.update(file) if (current[file] <=> previous[file]) != 0
end
end
def recache(base)
base = FSSM::Pathname.for(base)
previous = @cache.files
snapshot(base)
current = @cache.files
[previous, current]
end
def snapshot(base)
base = FSSM::Pathname.for(base)
@cache.unset(base)
@path.glob.each {|glob| add_glob(base, glob)}
end
def add_glob(base, glob)
FSSM::Pathname.glob(base.join(glob).to_s).each do |fn|
@cache.set(fn)
end
end
end

57
lib/vendor/fssm/fssm/state/directory.rb vendored Normal file
View File

@ -0,0 +1,57 @@
module FSSM::State
class Directory
attr_reader :path
def initialize(path)
@path = path
@cache = FSSM::Tree::Cache.new
end
def refresh(base=nil, skip_callbacks=false)
previous, current = recache(base || @path.to_pathname)
unless skip_callbacks
deleted(previous, current)
created(previous, current)
modified(previous, current)
end
end
private
def created(previous, current)
(current.keys - previous.keys).each {|created| @path.create(created)}
end
def deleted(previous, current)
(previous.keys - current.keys).each {|deleted| @path.delete(deleted)}
end
def modified(previous, current)
(current.keys & previous.keys).each do |file|
@path.update(file) if (current[file] <=> previous[file]) != 0
end
end
def recache(base)
base = FSSM::Pathname.for(base)
previous = @cache.files
snapshot(base)
current = @cache.files
[previous, current]
end
def snapshot(base)
base = FSSM::Pathname.for(base)
@cache.unset(base)
@path.glob.each {|glob| add_glob(base, glob)}
end
def add_glob(base, glob)
FSSM::Pathname.glob(base.join(glob).to_s).each do |fn|
@cache.set(fn)
end
end
end
end

24
lib/vendor/fssm/fssm/state/file.rb vendored Normal file
View File

@ -0,0 +1,24 @@
module FSSM::State
class File
attr_reader :path
def initialize(path)
@path = path
end
def refresh(base=nil, skip_callbacks=false)
base ||= @path.to_pathname
used_to_exist, @exists = @exists, base.exists?
# this handles bad symlinks without failing. why handle bad symlinks at
# all? well, we could still be interested in their creation and deletion.
old_mtime, @mtime = @mtime, base.symlink? ? Time.at(0) : base.mtime if @exists
unless skip_callbacks
@path.delete(@path.to_s) if used_to_exist && !@exists
@path.create(@path.to_s) if !used_to_exist && @exists
@path.update(@path.to_s) if used_to_exist && @exists && old_mtime != @mtime
end
end
end
end

View File

@ -37,15 +37,23 @@ module FSSM::Support
end end
def rb_inotify? def rb_inotify?
begin found = begin
require 'rubygems'
gem 'rb-inotify', '>= 0.3.0'
require 'rb-inotify' require 'rb-inotify'
true INotify::Notifier.ancestors.include?(IO)
rescue LoadError, Gem::LoadError rescue LoadError
STDERR.puts("Warning: Unable to load rb-inotify >= 0.3.0. Inotify will be unavailable.")
false false
end end
STDERR.puts("Warning: Unable to load rb-inotify >= 0.3.0. Inotify will be unavailable.") unless found
found
end
def use_block(context, block)
return if block.nil?
if block.arity == 1
block.call(context)
else
context.instance_eval(&block)
end
end end
end end