From 46976c62679325a1db9ee3b8b8dda54b71909e77 Mon Sep 17 00:00:00 2001 From: Flier Lu Date: Tue, 8 Sep 2015 18:21:03 +0800 Subject: [PATCH 1/2] use xattr to trace file instead of inode --- Gemfile | 2 ++ lib/filewatch/watch.rb | 17 +++++++++++++++++ spec/tail_spec.rb | 9 +++++++++ 3 files changed, 28 insertions(+) diff --git a/Gemfile b/Gemfile index 3f5f6ce..371875f 100644 --- a/Gemfile +++ b/Gemfile @@ -3,4 +3,6 @@ source "https://rubygems.org" group :test do gem 'rspec' gem 'stud', "~> 0.0.18" + gem 'uuid', "~> 2.3.8" + gem 'ffi-xattr', "~> 0.1.2" end diff --git a/lib/filewatch/watch.rb b/lib/filewatch/watch.rb index 9694eed..9be0e96 100644 --- a/lib/filewatch/watch.rb +++ b/lib/filewatch/watch.rb @@ -2,6 +2,8 @@ if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/ require "filewatch/winhelper" end +require "ffi-xattr" +require "uuid" module FileWatch class Watch @@ -19,6 +21,9 @@ def initialize(opts={}) @watching = [] @exclude = [] @files = Hash.new { |h, k| h[k] = Hash.new } + + @xattr = opts[:xattr] || 'uuid' + @uuid = UUID.new if @xattr end # def initialize public @@ -45,6 +50,18 @@ def watch(path) def inode(path,stat) if @iswindows fileId = Winhelper.GetWindowsUniqueFileIdentifier(path) + inode = [fileId, stat.dev_major, stat.dev_minor] + elsif @xattr + xattr = Xattr.new(path) + + fileId = xattr[@xattr] + + if !fileId + fileId = @uuid.generate + + xattr[@xattr] = fileId + end + inode = [fileId, stat.dev_major, stat.dev_minor] else inode = [stat.ino.to_s, stat.dev_major, stat.dev_minor] diff --git a/spec/tail_spec.rb b/spec/tail_spec.rb index 5ed047a..df0fec2 100644 --- a/spec/tail_spec.rb +++ b/spec/tail_spec.rb @@ -1,5 +1,6 @@ require 'filewatch/tail' require 'stud/temporary' +require 'ffi-xattr' describe FileWatch::Tail do @@ -21,6 +22,14 @@ it "reads new lines off the file" do expect { |b| subject.subscribe(&b) }.to yield_successive_args([file_path, "line1"], [file_path, "line2"]) end + + it "file contains xattr 'uuid'" do + subject.subscribe {|_,_| } + stat = File::Stat.new(file_path) + sincedb_id = subject.sincedb_record_uid(file_path,stat)[0] + + expect(Xattr.new(file_path)['uuid']).to eq(sincedb_id) + end end context "when watching a file" do From 7f52c39dee2ccfcc727239aac6e49db6de4af21a Mon Sep 17 00:00:00 2001 From: Flier Lu Date: Tue, 8 Sep 2015 18:24:17 +0800 Subject: [PATCH 2/2] rollback to inode when xattr not ready --- lib/filewatch/watch.rb | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/filewatch/watch.rb b/lib/filewatch/watch.rb index 9be0e96..c5140a1 100644 --- a/lib/filewatch/watch.rb +++ b/lib/filewatch/watch.rb @@ -52,17 +52,21 @@ def inode(path,stat) fileId = Winhelper.GetWindowsUniqueFileIdentifier(path) inode = [fileId, stat.dev_major, stat.dev_minor] elsif @xattr - xattr = Xattr.new(path) + begin + xattr = Xattr.new(path) - fileId = xattr[@xattr] + fileId = xattr[@xattr] - if !fileId - fileId = @uuid.generate + if !fileId + fileId = @uuid.generate - xattr[@xattr] = fileId - end + xattr[@xattr] = fileId + end - inode = [fileId, stat.dev_major, stat.dev_minor] + inode = [fileId, stat.dev_major, stat.dev_minor] + rescue + inode = [stat.ino.to_s, stat.dev_major, stat.dev_minor] + end else inode = [stat.ino.to_s, stat.dev_major, stat.dev_minor] end