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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1a2903e3cddd8da5107080ea930b4b410f4d7183
4
- data.tar.gz: 926996d000172e71d502019a646dc64b15171326
3
+ metadata.gz: fa437427fdd1f03240d821e5f1a54aab0b6355b0
4
+ data.tar.gz: aee28adbc8cc8fded7ec0d43814e5d85166b18f4
5
5
  SHA512:
6
- metadata.gz: 4a61d2ae2fdc622ba708f51f9137882d5091701b21a1135eef380674eb525aacd03b1e6240adbb5aac89ba7b42a015fe355a36d33744772d54b6b39368bcb59d
7
- data.tar.gz: 05a6a3d10b602fbf805f7dee69dab70d7065d58a0116bc4d46f200352601382dfd8869939173df5f97da2cc4b5f26cd8be00d01113de7007934cd597bd3923a0
6
+ metadata.gz: c5307f2e8fbe14b24a20026e3481fce94ec7b47003a4214faf75717b554b54bc2e081461cebf18db9f5eea920588f3beb22b0d6cb92de1b5909531b9ed077295
7
+ data.tar.gz: d73efb21eb53a20db71335a63580c0dc7526f440a056affd99979b35c4c01e3baea805549af4a5a2e97e6d81e4b2031230633ab159b326224953c0b3917b4994
data/.gitignore CHANGED
@@ -13,3 +13,4 @@
13
13
  *.a
14
14
  mkmf.log
15
15
  .idea
16
+ *.gem
@@ -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(filename, opts, &on_line)
17
+ def tail(file_path, opts, &on_line)
16
18
  @stopped = false
17
19
  seek_end = opts.fetch(:seek_end, true)
18
- sleep(0.25) until File.exists?(filename)
19
- File.open(filename) do |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(filename) { read_and_report_lines(file, unreported_line, &on_line) }
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
- case NotifiedTail.get_ruby_platform
54
- when /bsd/, /darwin/
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
- last_mtime = File.mtime(file_path)
66
- until @stopped do
67
- sleep(0.5)
68
- mtime = File.mtime(file_path)
69
- yield if mtime != last_mtime # use != instead of > to mitigate DST complications
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
@@ -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.1.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.1.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-27 00:00:00.000000000 Z
11
+ date: 2015-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler