Class: Ramaze::Reloader::WatchInotify

### Home Classes Methods

### In Files

- lib/ramaze/reloader/watch_inotify.rb

### Parent

Object

### Methods

- ::new
- #call
- #changed_files
- #close
- #remove_watch
- #start_watcher
- #watch
- #watcher_cycle

### Files

- Gemfile
- Rakefile

### Class/Module Index

Quicksearch

- Ramaze
- Ramaze::App
- Ramaze::Bin
- Ramaze::Bin::Create
- Ramaze::Bin::Runner
- Ramaze::Cache
- Ramaze::Cache::LRU
- Ramaze::Cache::LocalMemCache
- Ramaze::Cache::MemCache
- Ramaze::Cache::Redis
- Ramaze::Cache::Sequel
- Ramaze::Controller
- Ramaze::CoreExtensions
- Ramaze::CoreExtensions::Object
- Ramaze::CoreExtensions::String
- Ramaze::Current
- Ramaze::DefaultController
- Ramaze::Files
- Ramaze::Gestalt
- Ramaze::Helper
- Ramaze::Helper::Auth
- Ramaze::Helper::Bench
- Ramaze::Helper::BlueForm
- Ramaze::Helper::BlueForm::Form
- Ramaze::Helper::CSRF
- Ramaze::Helper::Cache
- Ramaze::Helper::Cache::SingletonMethods
- Ramaze::Helper::Email
- Ramaze::Helper::Erector
- Ramaze::Helper::Flash
- Ramaze::Helper::Formatting
- Ramaze::Helper::Gestalt
- Ramaze::Helper::Gravatar
- Ramaze::Helper::Identity
- Ramaze::Helper::Layout
- Ramaze::Helper::Layout::SingletonMethods
- Ramaze::Helper::Link
- Ramaze::Helper::Localize
- Ramaze::Helper::Localize::Dictionary
- Ramaze::Helper::Localize::Parser
- Ramaze::Helper::Markaby
- Ramaze::Helper::Maruku
- Ramaze::Helper::Paginate
- Ramaze::Helper::Paginate::Paginator
- Ramaze::Helper::Paginate::Paginator::ArrayPager
- Ramaze::Helper::Paginate::Paginator::DataMapperPager
- Ramaze::Helper::Remarkably
- Ramaze::Helper::RequestAccessor
- Ramaze::Helper::SendFile
- Ramaze::Helper::SimpleCaptcha
- Ramaze::Helper::Stack
- Ramaze::Helper::Thread
- Ramaze::Helper::Upload
- Ramaze::Helper::Upload::ClassMethods
- Ramaze::Helper::Upload::UploadedFile
- Ramaze::Helper::UserHelper
- Ramaze::Helper::UserHelper::Wrapper
- Ramaze::Helper::XHTML
- Ramaze::LRUHash
- Ramaze::Logger
- Ramaze::Logger::Informer
- Ramaze::Logger::LogHub
- Ramaze::Logger::Logger
- Ramaze::Logger::RotatingInformer
- Ramaze::Logger::Syslog
- Ramaze::Logging
- Ramaze::Reloader
- Ramaze::Reloader::Hooks
- Ramaze::Reloader::WatchInotify
- Ramaze::Reloader::WatchStat
- Ramaze::Request
- Ramaze::Response
- Ramaze::SpecLogger
- Ramaze::View
- Ramaze::View::Erector
- Ramaze::View::Erubis
- Ramaze::View::Ezamar
- Ramaze::View::Gestalt
- Ramaze::View::Haml
- Ramaze::View::Liquid
- Ramaze::View::Liquid::Tag
- Ramaze::View::Lokar
- Ramaze::View::Mustache
- Ramaze::View::Mustache::RamazeContext
- Ramaze::View::Nagoro
- Ramaze::View::Remarkably
- Ramaze::View::Sass
- Ramaze::View::Slippers
- Ramaze::View::Tagz
- Ramaze::View::Tagz::Methods
- Ramaze::View::Tenjin
- Innate
- Innate::View
- Innate::View::Slim
- Nagoro
- Nagoro::Pipe
- Nagoro::Pipe::RenderPartial
- Bacon
- Bacon::PrettyOutput
- Erector
- Erector::Widget
- Rack
- Rack::RouteExceptions
- Tenjin
- Tenjin::Template
- BlankSlate
- Controller
- MainController
- Object

No matching classes.

# Ramaze::Reloader::WatchInotify

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.

### Constants

NOTIFY_MASK
POLL_INTERVAL

### Public Class Methods

new() click to toggle source

    # File lib/ramaze/reloader/watch_inotify.rb, line 19
    def initialize
      @watcher = RInotify.new
      @changed = Queue.new
      @watcher_thread = start_watcher
    end

### Public Instance Methods

call(cooldown) click to toggle source

    # File lib/ramaze/reloader/watch_inotify.rb, line 25
    def call(cooldown)
      yield
    end

changed_files() click to toggle source

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.

    # 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

close() click to toggle source

    # File lib/ramaze/reloader/watch_inotify.rb, line 61
    def close
      @watcher_thread.terminate
      @watcher.close
      true
    end

remove_watch(file) click to toggle source

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.

    # File lib/ramaze/reloader/watch_inotify.rb, line 57
    def remove_watch(file)
      @watcher.rm_watch(file)
    end

start_watcher() click to toggle source

TODO: define a finalizer to cleanup? -- reloader never calls close

    # File lib/ramaze/reloader/watch_inotify.rb, line 31
    def start_watcher
      Thread.new{ loop{ watcher_cycle }}
    end

watch(file) click to toggle source

    # 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

watcher_cycle() click to toggle source

Not much work here, we just have to empty the event queue and push the descriptors for reloading on next request.

    # 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

[Validate]

Generated with the Darkfish Rdoc Generator 2.