Permalink
Browse files

Ported unix handler to eventmachine

  • Loading branch information...
1 parent e372a83 commit 10d44a532caab33bdfd18a544a5500d5242cd9dc @mynyml committed Sep 25, 2009
Showing with 63 additions and 71 deletions.
  1. +1 −2 lib/watchr.rb
  2. +19 −19 lib/watchr/event_handlers/unix.rb
  3. +39 −24 test/event_handlers/test_unix.rb
  4. +4 −26 test/test_watchr.rb
View
@@ -89,8 +89,7 @@ def handler
when /mswin|windows|cygwin/i
Watchr::EventHandler::Portable
when /sunos|solaris|darwin|mach|osx|bsd|linux/i, 'unix'
- #Watchr::EventHandler::Unix
- Watchr::EventHandler::Portable
+ Watchr::EventHandler::Unix
else
Watchr::EventHandler::Portable
end
@@ -1,29 +1,30 @@
-require 'rev'
+require 'eventmachine'
module Watchr
module EventHandler
class Unix
include Base
- # Used by Rev. Wraps a monitored path, and Rev::Loop will call its
- # callback on file events.
- class SingleFileWatcher < Rev::StatWatcher #:nodoc:
- class << self
- # Stores a reference back to handler so we can call its #nofity
- # method with file event info
- attr_accessor :handler
+ # Used by EventMachine. Wraps a monitored path, and EM will call its
+ # callbacks on file events.
+ class SingleFileWatcher < EM::FileWatch #:nodoc:
+
+ # ===== Parameters
+ # handler<EventHandler::Base>:: a handler object to notify
+ #
+ def initialize(handler)
+ @handler = handler
end
# Callback. Called on file change event
# Delegates to Controller#update, passing in path and event type
- def on_change
- self.class.handler.notify(path, :changed)
+ def file_modified
+ @handler.notify(path, :changed)
end
end
- def initialize
- SingleFileWatcher.handler = self
- @loop = Rev::Loop.default
+ def initialize #:nodoc:
+ @watchers = []
end
# Enters listening loop.
@@ -32,8 +33,7 @@ def initialize
#
def listen(monitored_paths)
@monitored_paths = monitored_paths
- attach
- @loop.run
+ EM.run { attach }
end
# Rebuilds file bindings.
@@ -42,20 +42,20 @@ def listen(monitored_paths)
#
def refresh(monitored_paths)
@monitored_paths = monitored_paths
- detach
- attach
+ EM.next_tick { detach; attach }
end
private
# Binds all <tt>monitored_paths</tt> to the listening loop.
def attach
- @monitored_paths.each {|path| SingleFileWatcher.new(path.to_s).attach(@loop) }
+ @monitored_paths.each {|p| @watchers << EM.watch_file(p.to_s, SingleFileWatcher, self) }
end
# Unbinds all paths currently attached to listening loop.
def detach
- @loop.watchers.each {|watcher| watcher.detach }
+ @watchers.each {|w| w.stop_watching }
+ @watchers.clear
end
end
end
@@ -1,58 +1,73 @@
-=begin
require 'test/test_helper'
+require 'eventmachine'
+
+module EM #alias for EventMachine
+ class << self
+ def run(&block)
+ block.call
+ end
+ def next_tick(&block)
+ block.call
+ end
+ def watch_file(path, handler, *args)
+ watcher = handler.new(:dummy, *args)
+ watcher.instance_variable_set(:@path, path)
+ watcher
+ end
+ end
+end
+
+class Watchr::EventHandler::Unix
+ attr_accessor :watchers
+end
class UnixEventHandlerTest < Test::Unit::TestCase
include Watchr
SingleFileWatcher = EventHandler::Unix::SingleFileWatcher
def setup
- @loop = Rev::Loop.default
@handler = EventHandler::Unix.new
- @loop.stubs(:run)
- end
-
- def teardown
- SingleFileWatcher.handler = nil
- Rev::Loop.default.watchers.every.detach
+ SingleFileWatcher.any_instance.stubs(:stop_watching)
end
test "triggers listening state" do
- @loop.expects(:run)
+ EM.expects(:run)
@handler.listen([])
end
## monitoring file events
test "listens for events on monitored files" do
@handler.listen %w( foo bar )
- @loop.watchers.size.should be(2)
- @loop.watchers.every.path.should include('foo', 'bar')
- @loop.watchers.every.class.uniq.should be([SingleFileWatcher])
+ @handler.watchers.size.should be(2)
+ @handler.watchers.every.path.should include('foo')
+ @handler.watchers.every.path.should include('bar')
end
test "notifies observers on file event" do
- watcher = SingleFileWatcher.new('foo/bar')
+ watcher = SingleFileWatcher.new(:dummy, @handler)
watcher.stubs(:path).returns('foo/bar')
@handler.expects(:notify).with('foo/bar', :changed)
- watcher.on_change
+ watcher.file_modified
end
## on the fly updates of monitored files list
- test "reattaches to new monitored files" do
+ test "attaches new monitored files" do
@handler.listen %w( foo bar )
- @loop.watchers.size.should be(2)
- @loop.watchers.every.path.should include('foo')
- @loop.watchers.every.path.should include('bar')
+ @handler.watchers.size.should be(2)
+ @handler.watchers.every.path.should include('foo')
+ @handler.watchers.every.path.should include('bar')
+
+ SingleFileWatcher.any_instance.expects(:stop_watching).twice
@handler.refresh %w( baz bax )
- @loop.watchers.size.should be(2)
- @loop.watchers.every.path.should include('baz')
- @loop.watchers.every.path.should include('bax')
- @loop.watchers.every.path.should exclude('foo')
- @loop.watchers.every.path.should exclude('bar')
+ @handler.watchers.size.should be(2)
+ @handler.watchers.every.path.should include('baz')
+ @handler.watchers.every.path.should include('bax')
+ @handler.watchers.every.path.should exclude('foo')
+ @handler.watchers.every.path.should exclude('bar')
end
end
-=end
View
@@ -23,43 +23,21 @@ def setup
end
test "picking handler" do
-
- # temporary workaround to issue #1
- # http://github.com/mynyml/watchr/issues#issue/1
-
- #Watchr.handler = nil
- #ENV['HANDLER'] = 'linux'
- #Watchr.handler.should be(Watchr::EventHandler::Unix)
-
- #Watchr.handler = nil
- #ENV['HANDLER'] = 'bsd'
- #Watchr.handler.should be(Watchr::EventHandler::Unix)
-
- #Watchr.handler = nil
- #ENV['HANDLER'] = 'darwin'
- #Watchr.handler.should be(Watchr::EventHandler::Unix)
-
- #Watchr.handler = nil
- #ENV['HANDLER'] = 'unix'
- #Watchr.handler.should be(Watchr::EventHandler::Unix)
-
Watchr.handler = nil
ENV['HANDLER'] = 'linux'
- Watchr.handler.should be(Watchr::EventHandler::Portable)
+ Watchr.handler.should be(Watchr::EventHandler::Unix)
Watchr.handler = nil
ENV['HANDLER'] = 'bsd'
- Watchr.handler.should be(Watchr::EventHandler::Portable)
+ Watchr.handler.should be(Watchr::EventHandler::Unix)
Watchr.handler = nil
ENV['HANDLER'] = 'darwin'
- Watchr.handler.should be(Watchr::EventHandler::Portable)
+ Watchr.handler.should be(Watchr::EventHandler::Unix)
Watchr.handler = nil
ENV['HANDLER'] = 'unix'
- Watchr.handler.should be(Watchr::EventHandler::Portable)
- # end temporary workaround
-
+ Watchr.handler.should be(Watchr::EventHandler::Unix)
Watchr.handler = nil
ENV['HANDLER'] = 'mswin'

0 comments on commit 10d44a5

Please sign in to comment.