On 11/22/06, [email protected] [email protected] wrote:
how is this working for you? i think when i looked into inotify i found that
messages would get sent twice or not at all or out of order or something like
that… i forget this exact issues. have you seen any? btw. could i/we have
a look at your code?
Code inlined (not sure how the usenet and forum sides handle actual
attachments) - one watcher.rb per node and one process-inotify sitting
on the server.
martin
— watcher.rb —
require ‘inotify’
require ‘find’
require ‘drb’
DRb.start_service
$www = DRbObject.new(nil, ‘druby://www:7777’)
EVENTS = {
Inotify::CREATE => “created”,
Inotify::DELETE => “deleted”
}
ACTIONS = {
Inotify::CREATE => :from_inotify,
Inotify::MOVED_TO => :from_inotify,
Inotify::MOVED_FROM => :delete_from_inotify,
Inotify::DELETE => :delete_from_inotify
}
HOME_WATCHES = {}
INOTIFY_WATCHES = {}
HOME = Inotify.new
INOTIFY = Inotify.new
def watch(user)
dir = File.join(’/home’, user)
begin
wd = INOTIFY.add_watch(dir, Inotify::CREATE | Inotify::DELETE |
Inotify::MOVED_TO)
INOTIFY_WATCHES[wd] = user
rescue Exception => e
puts “Skipping #{e}: #{$!}”
end
end
watch the home directory
HOME.add_watch("/home", Inotify::CREATE | Inotify::ISDIR)
Thread.new do
HOME.each_event {|ev|
p [“HOME”, ev]
if ev.mask == Inotify::CREATE | Inotify::ISDIR
newusr = ev.name
watch(newusr)
end
}
end
watch all the user subdirectories
Dir[’/home/*’].each {|dir|
user = File.basename(dir)
watch(user)
}
t = Thread.new do
INOTIFY.each_event {|ev|
# skip hidden files
unless ev.name =~ /^./
user = INOTIFY_WATCHES[ev.wd]
str = ev.name
action = ACTIONS[ev.mask]
if action
begin
$www.incoming(‘resource’, user, action, str)
rescue Exception => e
puts “!! exception: #{e}”
end
end
end
}
end
t.join
— process-inotify.rb —
#!usr/bin/ruby
require ‘rubygems’
require ‘active_record’
require ‘config/environment’
require ‘app/models/user’
require ‘app/models/resource’
require ‘drb’
require ‘inotify’
require ‘find’
require ‘thread’
require ‘logger’
queue incoming events
$incoming = Queue.new
class InotifyListener
def incoming(*args)
$incoming << args
end
end
DRb.start_service(“druby://:7777”, InotifyListener.new)
LOG = Logger.new(‘log/inotify.log’)
def log(msg)
LOG.info(msg)
end
log “opening db connection…”
db_config = YAML::load(File.open(“config/database.yml”))
ActiveRecord::Base.establish_connection(db_config[‘production’])
log “done!”
t = Thread.new do
loop do
if $incoming.empty?
sleep 1
next
else
begin
signal = $incoming.shift
log signal.inspect
recv, username, action, file = signal
user = User.find_by_login(username)
unless user
log “Unrecognized user #{username}: #{[recv, action,
file].inspect}”
next
end
if action
begin
Resource.send(action.to_sym, user, file)
rescue Exception => e
log “!! exception: #{e}”
end
end
rescue Exception => e1
log “!! exception: #{e1}”
end
end
end
end
DRb.thread.join