notified_tail 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/lib/notified_tail.rb +37 -21
- data/notified_tail.gemspec +1 -1
- data/spec/lib/notified_tail_spec.rb +12 -3
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: fa437427fdd1f03240d821e5f1a54aab0b6355b0
         | 
| 4 | 
            +
              data.tar.gz: aee28adbc8cc8fded7ec0d43814e5d85166b18f4
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: c5307f2e8fbe14b24a20026e3481fce94ec7b47003a4214faf75717b554b54bc2e081461cebf18db9f5eea920588f3beb22b0d6cb92de1b5909531b9ed077295
         | 
| 7 | 
            +
              data.tar.gz: d73efb21eb53a20db71335a63580c0dc7526f440a056affd99979b35c4c01e3baea805549af4a5a2e97e6d81e4b2031230633ab159b326224953c0b3917b4994
         | 
    
        data/.gitignore
    CHANGED
    
    
    
        data/lib/notified_tail.rb
    CHANGED
    
    | @@ -8,22 +8,25 @@ class NotifiedTail | |
| 8 8 | 
             
              # @option opts [Boolean] seek_end (true)
         | 
| 9 9 | 
             
              #   If true, seeks to the end of the file before reporting lines.
         | 
| 10 10 | 
             
              #   Otherwise, reports all lines starting at the beginning of the file.
         | 
| 11 | 
            +
              # @option opts [Boolean] force_poll (false)
         | 
| 12 | 
            +
              #   Poll even if inotify or kqueue are available
         | 
| 11 13 | 
             
              def self.tail(file_path, opts={}, &on_line)
         | 
| 12 14 | 
             
                new.tail(file_path, opts, &on_line)
         | 
| 13 15 | 
             
              end
         | 
| 14 16 |  | 
| 15 | 
            -
              def tail( | 
| 17 | 
            +
              def tail(file_path, opts, &on_line)
         | 
| 16 18 | 
             
                @stopped = false
         | 
| 17 19 | 
             
                seek_end = opts.fetch(:seek_end, true)
         | 
| 18 | 
            -
                 | 
| 19 | 
            -
                File. | 
| 20 | 
            +
                @force_poll = opts.fetch(:force_poll, false)
         | 
| 21 | 
            +
                sleep(0.25) until File.exists?(file_path)
         | 
| 22 | 
            +
                File.open(file_path) do |file|
         | 
| 20 23 | 
             
                  unreported_line = ''
         | 
| 21 24 | 
             
                  if seek_end
         | 
| 22 25 | 
             
                    file.seek(0, IO::SEEK_END)
         | 
| 23 26 | 
             
                  else
         | 
| 24 27 | 
             
                    read_and_report_lines(file, unreported_line, &on_line)
         | 
| 25 28 | 
             
                  end
         | 
| 26 | 
            -
                  when_modified( | 
| 29 | 
            +
                  when_modified(file_path) { read_and_report_lines(file, unreported_line, &on_line) }
         | 
| 27 30 | 
             
                end
         | 
| 28 31 | 
             
              end
         | 
| 29 32 |  | 
| @@ -49,25 +52,38 @@ class NotifiedTail | |
| 49 52 | 
             
                # done for now
         | 
| 50 53 | 
             
              end
         | 
| 51 54 |  | 
| 52 | 
            -
              def when_modified(file_path)
         | 
| 53 | 
            -
                 | 
| 54 | 
            -
             | 
| 55 | 
            -
                  require 'rb-kqueue'
         | 
| 56 | 
            -
                  @queue = KQueue::Queue.new
         | 
| 57 | 
            -
                  @queue.watch_file(ARGV.first, :extend) { yield }
         | 
| 58 | 
            -
                  @queue.run
         | 
| 59 | 
            -
                when /linux/
         | 
| 60 | 
            -
                  require 'rb-inotify'
         | 
| 61 | 
            -
                  @queue = INotify::Notifier.new
         | 
| 62 | 
            -
                  @queue.watch(file_path, :modify) { yield }
         | 
| 63 | 
            -
                  @queue.run
         | 
| 55 | 
            +
              def when_modified(file_path, &block)
         | 
| 56 | 
            +
                if @force_poll
         | 
| 57 | 
            +
                  poll(file_path, &block)
         | 
| 64 58 | 
             
                else
         | 
| 65 | 
            -
                   | 
| 66 | 
            -
                   | 
| 67 | 
            -
                     | 
| 68 | 
            -
                     | 
| 69 | 
            -
                     | 
| 59 | 
            +
                  case NotifiedTail.get_ruby_platform
         | 
| 60 | 
            +
                  when /bsd/, /darwin/
         | 
| 61 | 
            +
                    require 'rb-kqueue'
         | 
| 62 | 
            +
                    @queue = KQueue::Queue.new
         | 
| 63 | 
            +
                    @queue.watch_file(file_path, :extend) { block.call }
         | 
| 64 | 
            +
                    @queue.run
         | 
| 65 | 
            +
                  when /linux/
         | 
| 66 | 
            +
                    require 'rb-inotify'
         | 
| 67 | 
            +
                    @queue = INotify::Notifier.new
         | 
| 68 | 
            +
                    @queue.watch(file_path, :modify) { block.call }
         | 
| 69 | 
            +
                    @queue.run
         | 
| 70 | 
            +
                  else
         | 
| 71 | 
            +
                    poll(file_path, &block)
         | 
| 72 | 
            +
                  end
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
              end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
              def poll(file_path, &block)
         | 
| 77 | 
            +
                last_mtime = File.mtime(file_path)
         | 
| 78 | 
            +
                last_notify_time = nil
         | 
| 79 | 
            +
                until @stopped do
         | 
| 80 | 
            +
                  sleep(0.5)
         | 
| 81 | 
            +
                  mtime = File.mtime(file_path)
         | 
| 82 | 
            +
                  changed = mtime != last_mtime
         | 
| 83 | 
            +
                  if changed || last_notify_time == nil || (Time.now - last_notify_time) > 5
         | 
| 70 84 | 
             
                    last_mtime = mtime
         | 
| 85 | 
            +
                    last_notify_time = Time.now
         | 
| 86 | 
            +
                    block.call
         | 
| 71 87 | 
             
                  end
         | 
| 72 88 | 
             
                end
         | 
| 73 89 | 
             
              end
         | 
    
        data/notified_tail.gemspec
    CHANGED
    
    | @@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) | |
| 4 4 |  | 
| 5 5 | 
             
            Gem::Specification.new do |spec|
         | 
| 6 6 | 
             
              spec.name          = 'notified_tail'
         | 
| 7 | 
            -
              spec.version       = '0. | 
| 7 | 
            +
              spec.version       = '0.2.0'
         | 
| 8 8 | 
             
              spec.authors       = ['Peter Winton']
         | 
| 9 9 | 
             
              spec.email         = ['pwinton@indigobio.com']
         | 
| 10 10 | 
             
              spec.summary       = %q{Low latency file tailing in ruby}
         | 
| @@ -4,6 +4,8 @@ require 'notified_tail' | |
| 4 4 |  | 
| 5 5 | 
             
            describe NotifiedTail do
         | 
| 6 6 | 
             
              describe '#tail' do
         | 
| 7 | 
            +
                let!(:seek_end) { false }
         | 
| 8 | 
            +
                let!(:force_poll) { false }
         | 
| 7 9 |  | 
| 8 10 | 
             
                shared_examples 'tail -f' do
         | 
| 9 11 | 
             
                  let!(:lines) { [] }
         | 
| @@ -16,7 +18,7 @@ describe NotifiedTail do | |
| 16 18 |  | 
| 17 19 | 
             
                    watcher = Thread.start do
         | 
| 18 20 | 
             
                      notifier = NotifiedTail.new
         | 
| 19 | 
            -
                      notifier.tail(fn, seek_end: seek_end) do |line|
         | 
| 21 | 
            +
                      notifier.tail(fn, seek_end: seek_end, force_poll: force_poll) do |line|
         | 
| 20 22 | 
             
                        puts "saw #{line.inspect}"
         | 
| 21 23 | 
             
                        expect(line).to eql expected.first
         | 
| 22 24 | 
             
                        expected.shift
         | 
| @@ -51,13 +53,11 @@ describe NotifiedTail do | |
| 51 53 | 
             
                end
         | 
| 52 54 |  | 
| 53 55 | 
             
                context 'when not seeking to the end' do
         | 
| 54 | 
            -
                  let!(:seek_end) { false }
         | 
| 55 56 | 
             
                  it_behaves_like 'tail -f -n 9999PB'
         | 
| 56 57 | 
             
                end
         | 
| 57 58 |  | 
| 58 59 | 
             
                context 'when the platform does not support notifications' do
         | 
| 59 60 | 
             
                  before(:each) { allow(NotifiedTail).to receive(:get_ruby_platform).and_return('wha??') }
         | 
| 60 | 
            -
                  let!(:seek_end) { false }
         | 
| 61 61 | 
             
                  it_behaves_like 'tail -f -n 9999PB'
         | 
| 62 62 | 
             
                end
         | 
| 63 63 |  | 
| @@ -66,5 +66,14 @@ describe NotifiedTail do | |
| 66 66 | 
             
                  it_behaves_like 'tail -f -n 0'
         | 
| 67 67 | 
             
                end
         | 
| 68 68 |  | 
| 69 | 
            +
                context 'when forcing polling' do
         | 
| 70 | 
            +
                  let!(:force_poll) { true }
         | 
| 71 | 
            +
                  before(:each) do
         | 
| 72 | 
            +
                    expect(INotify::Notifier).to_not receive(:new) if defined?(INotify::Notifier)
         | 
| 73 | 
            +
                    expect(KQueue::Queue).to_not receive(:new) if defined?(KQueue::Queue)
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
                  it_behaves_like 'tail -f -n 9999PB'
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
             | 
| 69 78 | 
             
              end
         | 
| 70 79 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: notified_tail
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.2.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Peter Winton
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2015-10- | 
| 11 | 
            +
            date: 2015-10-29 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         |