Class: Ramaze::Reloader::WatchInotify
- Inherits:
-
Object
- Object
- Ramaze::Reloader::WatchInotify
- Defined in:
- lib/ramaze/reloader/watch_inotify.rb
Overview
TODO: * There seems to be a problem somewhere that I couldn't identify yet, a file has to be modified twice initially to make it show up as modified here, subsequent changes work just fine. The only workaround I could find right now would be to read/write every single file, but that would be unexpected, irresponsible, and error-prone.
NOTE: * I have changed from using a Mutex to using a Queue, which uses a Mutex internally.
Constant Summary
- POLL_INTERVAL =
seconds
2
- NOTIFY_MASK =
RInotify::MODIFY | RInotify::IN_ONESHOT
Instance Method Summary (collapse)
-
- (Object) call(cooldown)
-
- (Object) changed_files
NOTE: We have to add the changed file again after we got a notification, I have no idea why, but using IN_ONESHOT should make sure that there is no memory leak in the C level even if we add a file again.
-
- (Object) close
-
- (WatchInotify) initialize
constructor
A new instance of WatchInotify.
-
- (Object) remove_watch(file)
FIXME: Seems like this won't work due to some bug in the rinotify library.
-
- (Object) start_watcher
TODO: define a finalizer to cleanup? -- reloader never calls #close.
-
- (Object) watch(file)
-
- (Object) watcher_cycle
Not much work here, we just have to empty the event queue and push the descriptors for reloading on next request.
Constructor Details
- (WatchInotify) initialize
Returns a new instance of WatchInotify
19 20 21 22 23 |
# File 'lib/ramaze/reloader/watch_inotify.rb', line 19 def initialize @watcher = RInotify.new @changed = Queue.new @watcher_thread = start_watcher end |
Instance Method Details
- (Object) call(cooldown)
25 26 27 |
# File 'lib/ramaze/reloader/watch_inotify.rb', line 25 def call(cooldown) yield end |
- (Object) changed_files
NOTE: We have to add the changed file again after we got a notification, I have no idea why, but using IN_ONESHOT should make sure that there is no memory leak in the C level even if we add a file again. There is a memory leak however in the watch_descriptors hash, since rinotify won't synchronize the contents properly and will only add to the hash, so we have to clean up ourselves.
74 75 76 77 78 79 80 81 |
# File 'lib/ramaze/reloader/watch_inotify.rb', line 74 def changed_files until @changed.empty? descriptor = @changed.shift file = @watcher.watch_descriptors.delete(descriptor) watch(file) yield(file) end end |
- (Object) close
61 62 63 64 65 |
# File 'lib/ramaze/reloader/watch_inotify.rb', line 61 def close @watcher_thread.terminate @watcher.close true end |
- (Object) remove_watch(file)
FIXME: Seems like this won't work due to some bug in the rinotify library. Would be cool if someone could make a FFI version.
57 58 59 |
# File 'lib/ramaze/reloader/watch_inotify.rb', line 57 def remove_watch(file) @watcher.rm_watch(file) end |
- (Object) start_watcher
TODO: define a finalizer to cleanup? -- reloader never calls #close
31 32 33 |
# File 'lib/ramaze/reloader/watch_inotify.rb', line 31 def start_watcher Thread.new{ loop{ watcher_cycle }} end |
- (Object) watch(file)
45 46 47 48 49 50 51 52 |
# File 'lib/ramaze/reloader/watch_inotify.rb', line 45 def watch(file) return if @watcher.watch_descriptors.has_value?(file) return unless File.exist?(file) @watcher.add_watch(file, NOTIFY_MASK) rescue Errno::ENOENT retry end |
- (Object) watcher_cycle
Not much work here, we just have to empty the event queue and push the descriptors for reloading on next request.
37 38 39 40 41 42 43 |
# File 'lib/ramaze/reloader/watch_inotify.rb', line 37 def watcher_cycle return unless @watcher.wait_for_events(POLL_INTERVAL) @watcher.each_event do |event| @changed.push(event.watch_descriptor) end end |