listen 2.7.11 → 2.7.12
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/.hound.yml +3 -0
- data/.rubocop.yml +20 -232
- data/.rubocop_todo.yml +33 -0
- data/CONTRIBUTING.md +5 -5
- data/Gemfile +1 -0
- data/Guardfile +12 -9
- data/README.md +15 -29
- data/Rakefile +8 -1
- data/TROUBLESHOOTING.md +139 -0
- data/lib/listen.rb +6 -5
- data/lib/listen/adapter.rb +2 -1
- data/lib/listen/adapter/base.rb +7 -3
- data/lib/listen/adapter/darwin.rb +16 -1
- data/lib/listen/adapter/tcp.rb +8 -5
- data/lib/listen/adapter/windows.rb +6 -6
- data/lib/listen/change.rb +3 -2
- data/lib/listen/cli.rb +1 -3
- data/lib/listen/directory.rb +7 -11
- data/lib/listen/file.rb +35 -41
- data/lib/listen/internals/logging.rb +31 -0
- data/lib/listen/internals/thread_pool.rb +19 -0
- data/lib/listen/listener.rb +14 -14
- data/lib/listen/record.rb +2 -2
- data/lib/listen/silencer.rb +3 -3
- data/lib/listen/tcp/broadcaster.rb +8 -5
- data/lib/listen/version.rb +1 -1
- data/listen.gemspec +2 -2
- data/spec/acceptance/listen_spec.rb +1 -2
- data/spec/acceptance/tcp_spec.rb +4 -1
- data/spec/lib/listen/adapter/darwin_spec.rb +108 -0
- data/spec/lib/listen/adapter/polling_spec.rb +1 -0
- data/spec/lib/listen/file_spec.rb +20 -20
- data/spec/lib/listen/listener_spec.rb +1 -1
- data/spec/lib/listen/record_spec.rb +1 -1
- data/spec/lib/listen/silencer_spec.rb +4 -4
- data/spec/spec_helper.rb +4 -0
- data/spec/support/acceptance_helper.rb +2 -4
- data/vendor/hound/config/style_guides/ruby.yml +259 -0
- metadata +8 -2
data/Rakefile
CHANGED
@@ -2,4 +2,11 @@ require 'bundler/gem_tasks'
|
|
2
2
|
require 'rspec/core/rake_task'
|
3
3
|
|
4
4
|
RSpec::Core::RakeTask.new(:spec)
|
5
|
-
|
5
|
+
|
6
|
+
if ENV["CI"] != "true"
|
7
|
+
require "rubocop/rake_task"
|
8
|
+
RuboCop::RakeTask.new(:rubocop)
|
9
|
+
task default: [:spec, :rubocop]
|
10
|
+
else
|
11
|
+
task default: [:spec]
|
12
|
+
end
|
data/TROUBLESHOOTING.md
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
# Issues and troubleshooting
|
2
|
+
|
3
|
+
## 3 steps before you start diagnosing problems
|
4
|
+
|
5
|
+
These 3 steps will:
|
6
|
+
* help quickly troubleshoot issues caused by obscure problems
|
7
|
+
* help quickly identify the area of the problem (a full list is [below](#known-issues))
|
8
|
+
* help you get familiar with listen's diagnostic mode
|
9
|
+
* help you create relevant output before you submit an issue
|
10
|
+
|
11
|
+
1) For effective troubleshooting set the `LISTEN_GEM_DEBUGGING=1` variable
|
12
|
+
before starting listen.
|
13
|
+
|
14
|
+
2) Verify polling works (see `force_polling` option).
|
15
|
+
|
16
|
+
After starting listen, you should see something like:
|
17
|
+
```
|
18
|
+
INFO -- : Celluloid loglevel set to: 1
|
19
|
+
INFO -- : Record.build(): 0.06773114204406738 seconds
|
20
|
+
```
|
21
|
+
|
22
|
+
(Listen uses [Celluloid](https://github.com/celluloid/celluloid) for logging, so if you don't see anything, `Celluloid.logger` might have been disabled by a different gem, e.g. sidekiq)
|
23
|
+
|
24
|
+
If you don't see the line `Record.build()`:
|
25
|
+
* and there's a lot of disk activity, you may have to wait a few seconds
|
26
|
+
* you may be using an outdated version of Listen
|
27
|
+
* listen may have got stuck on a recursive symlink, see #259
|
28
|
+
|
29
|
+
3) Make changes e.g. `touch foo` or `echo "a" >> foo` (for troubleshooting, avoid using an editor which could generate too many misleading events)
|
30
|
+
|
31
|
+
You should see something like:
|
32
|
+
|
33
|
+
```
|
34
|
+
INFO -- : listen: raw changes: [[:added, "/home/me/foo"]]
|
35
|
+
INFO -- : listen: final changes: {:modified=>[], :added=>["/home/me/foo"], :removed=>[]}
|
36
|
+
```
|
37
|
+
|
38
|
+
"raw changes" contains changes collected during the `:wait_for_delay` and `:latency` intervals, while "final changes" is what listen decided are relevant changes (for better editor support).
|
39
|
+
|
40
|
+
## Adapter-specific diagnostics
|
41
|
+
|
42
|
+
Use the `LISTEN_GEM_DEBUGGING` set to `2` for additional info.
|
43
|
+
|
44
|
+
E.g. you'll get:
|
45
|
+
|
46
|
+
```
|
47
|
+
INFO -- : Celluloid loglevel set to: 0
|
48
|
+
DEBUG -- : Broadcaster: starting tcp server: 127.0.0.1:4000
|
49
|
+
DEBUG -- : Adapter: considering TCP ...
|
50
|
+
DEBUG -- : Adapter: considering polling ...
|
51
|
+
DEBUG -- : Adapter: considering optimized backend...
|
52
|
+
INFO -- : Record.build(): 0.0007264614105224609 seconds
|
53
|
+
DEBUG -- : inotify: foo ([:create])
|
54
|
+
DEBUG -- : raw queue: [:file, #<Pathname:/tmp/x>, "foo", {:change=>:added}]
|
55
|
+
DEBUG -- : added: file:/tmp/x/foo ({:change=>:added})
|
56
|
+
DEBUG -- : inotify: foo ([:attrib])
|
57
|
+
DEBUG -- : raw queue: [:file, #<Pathname:/tmp/x>, "foo", {:change=>:modified}]
|
58
|
+
DEBUG -- : inotify: foo ([:close_write, :close])
|
59
|
+
DEBUG -- : raw queue: [:file, #<Pathname:/tmp/x>, "foo", {:change=>:modified}]
|
60
|
+
DEBUG -- : modified: file:/tmp/x/foo ({:change=>:modified})
|
61
|
+
DEBUG -- : modified: file:/tmp/x/foo ({:change=>:modified})
|
62
|
+
INFO -- : listen: raw changes: [[:added, "/tmp/x/foo"]]
|
63
|
+
INFO -- : listen: final changes: {:modified=>[], :added=>["/tmp/x/foo"], :removed=>[]}
|
64
|
+
DEBUG -- : Callback took 4.410743713378906e-05 seconds
|
65
|
+
```
|
66
|
+
|
67
|
+
This shows:
|
68
|
+
* host port listened to (for forwarding events)
|
69
|
+
* the actual adapter used (here, it's "optimized backend")
|
70
|
+
* the event received (here it's `:create` from rb-inotify)
|
71
|
+
* "raw queue" - events queued for processing (collected during `:latency`)
|
72
|
+
* "Callback took" - how long it took your app to process changes
|
73
|
+
|
74
|
+
#### Known issues
|
75
|
+
|
76
|
+
Here are common issues grouped by area in which they occur:
|
77
|
+
|
78
|
+
1. System/OS
|
79
|
+
* [Update your Dropbox client](http://www.dropbox.com/downloading), if you have Dropbox installed.
|
80
|
+
* old MacOS (< 10.6)
|
81
|
+
* certain old versions of Ruby (try a newer Ruby on Windows for `wdm` and TCP mode to work)
|
82
|
+
* system limits
|
83
|
+
* threads for Celluloid (e.g. Virtual Machine CPU/RAM limitations)
|
84
|
+
* [inotify limits (Linux)](https://github.com/guard/listen/wiki/Increasing-the-amount-of-inotify-watchers)
|
85
|
+
* system in an inconsistent state or stuck (try rebooting/updating on Windows/Mac - seriously!)
|
86
|
+
* FSEvent bug: (http://feedback.livereload.com/knowledgebase/articles/86239)
|
87
|
+
|
88
|
+
2. Installation/gems/config
|
89
|
+
* not running listen or your app (e.g. guard) with `bundle exec` first
|
90
|
+
* old version of listen
|
91
|
+
* problems with adapter gems (`wdm`, `rb-fsevent`, `rb-inotify`) not installed, not detected properly (Windows) or not in Gemfile (Windows)
|
92
|
+
* Celluloid actors are silently crashing (when no LISTEN_GEM_DEBUGGING variable is present)
|
93
|
+
* see the [Performance](https://github.com/guard/listen/blob/master/README.md#Performance) section in the README
|
94
|
+
|
95
|
+
3. Filesystem
|
96
|
+
* VM shared folders and network folders (NFS, Samba, SSHFS) don't work with optimized backends (workaround: polling, [TCP mode](https://github.com/guard/listen/blob/master/README.md#forwarding-file-events-over-tcp), Vagrant's rsync-auto mode, rsync/unison)
|
97
|
+
* FAT/HFS timestamps have 1-second precision, which can cause polling and rb-fsevent to be very slow on large files (try `LISTEN_GEM_DISABLE_HASHING` variable)
|
98
|
+
* virtual filesystems may not implement event monitoring
|
99
|
+
* restrictive file/folder permissions
|
100
|
+
* watched folders moved/removed while listen was running (try restarting listen and moving/copying watched folder to a new location)
|
101
|
+
|
102
|
+
4. Insufficient latency (for polling and rb-fsevent)
|
103
|
+
* too many files being watched (polling) and not enough threads or CPU power
|
104
|
+
* slow editor save (see below)
|
105
|
+
* slow hard drive
|
106
|
+
* encryption
|
107
|
+
* a combination of factors
|
108
|
+
|
109
|
+
5. Too few or too many callbacks (`:wait_for_delay` option)
|
110
|
+
* complex editor file-save causes events to happen during callback (result: multiple callbacks if wait_for_delay is too small)
|
111
|
+
* too large when using TCP mode (see timestamps in output to debug)
|
112
|
+
* too many changes happening too frequently (use ignore rules to filter them out)
|
113
|
+
|
114
|
+
6. Paths
|
115
|
+
* default ignore rules
|
116
|
+
* encoding-related issues (bad filenames, mounted FS encoding mismatch)
|
117
|
+
* symlinks may cause listen to hang (#259)
|
118
|
+
* symlinks may not work as you expect or work differently for polling vs non-polling
|
119
|
+
* TCP paths don't match with client's current working directory
|
120
|
+
|
121
|
+
7. Editors
|
122
|
+
* "atomic save" in editors may confuse listen (disable it and try again)
|
123
|
+
* listen's default ignore rules may need tweaking
|
124
|
+
* your editor may not be supported yet (see default ignore rules for editors)
|
125
|
+
* use `touch foo` or `echo "a" >> foo` to confirm it's an editor issue
|
126
|
+
* slow terminal/GFX card, slow font, transparency effects in terminal
|
127
|
+
* complex/lengthy editor save (due to e.g. many plugins running during save)
|
128
|
+
* listen has complex rules for detecting atomic file saves (Linux)
|
129
|
+
|
130
|
+
8. TCP (tcp mode) issues
|
131
|
+
* not a recent listen gem (before 2.7.11)
|
132
|
+
* additional network delay and collecting may need a higher `:wait_for_delay` value
|
133
|
+
* changes (added, removed, deleted) not matching actual changes
|
134
|
+
|
135
|
+
If your application keeps using the polling-adapter and you can't figure out why, feel free to [open an issue](https://github.com/guard/listen/issues/new) (and be sure to [give all the details](https://github.com/guard/listen/blob/master/CONTRIBUTING.md)).
|
136
|
+
|
137
|
+
Listen traps SIGINT signal to properly finalize listeners. If you plan
|
138
|
+
on trapping this signal yourself - make sure to call `Listen.stop` in
|
139
|
+
signal handler.
|
data/lib/listen.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'celluloid'
|
2
2
|
require 'listen/listener'
|
3
3
|
|
4
|
+
require 'listen/internals/thread_pool'
|
5
|
+
|
4
6
|
module Listen
|
5
7
|
class << self
|
6
8
|
# Listens to file system modifications on a either single directory or
|
@@ -21,11 +23,9 @@ module Listen
|
|
21
23
|
def to(*args, &block)
|
22
24
|
Celluloid.boot unless Celluloid.running?
|
23
25
|
options = args.last.is_a?(Hash) ? args.last : {}
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
_add_listener(*args, &block)
|
28
|
-
end
|
26
|
+
target = options.delete(:forward_to)
|
27
|
+
args = ([target, :broadcaster] + args) if target
|
28
|
+
_add_listener(*args, &block)
|
29
29
|
end
|
30
30
|
|
31
31
|
# Stop all listeners & Celluloid
|
@@ -36,6 +36,7 @@ module Listen
|
|
36
36
|
# This is used by the `listen` binary to handle Ctrl-C
|
37
37
|
#
|
38
38
|
def stop
|
39
|
+
Internals::ThreadPool.stop
|
39
40
|
@listeners ||= []
|
40
41
|
|
41
42
|
# TODO: should use a mutex for this
|
data/lib/listen/adapter.rb
CHANGED
data/lib/listen/adapter/base.rb
CHANGED
@@ -28,7 +28,7 @@ module Listen
|
|
28
28
|
defaults = self.class.const_get('DEFAULTS')
|
29
29
|
@options = Listen::Options.new(options, defaults)
|
30
30
|
rescue
|
31
|
-
|
31
|
+
_log_exception 'adapter config failed: %s:%s'
|
32
32
|
raise
|
33
33
|
end
|
34
34
|
|
@@ -53,11 +53,11 @@ module Listen
|
|
53
53
|
|
54
54
|
def start
|
55
55
|
configure
|
56
|
-
|
56
|
+
Listen::Internals::ThreadPool.add do
|
57
57
|
begin
|
58
58
|
_run
|
59
59
|
rescue
|
60
|
-
|
60
|
+
_log_exception 'run() in thread failed: %s:%s'
|
61
61
|
raise
|
62
62
|
end
|
63
63
|
end
|
@@ -83,6 +83,10 @@ module Listen
|
|
83
83
|
self.class.send(:_log, *args)
|
84
84
|
end
|
85
85
|
|
86
|
+
def _log_exception(msg)
|
87
|
+
_log :error, format(msg, $ERROR_INFO, $ERROR_POSITION * "\n")
|
88
|
+
end
|
89
|
+
|
86
90
|
def self._log(*args)
|
87
91
|
Celluloid::Logger.send(*args)
|
88
92
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'listen/internals/thread_pool'
|
2
|
+
|
1
3
|
module Listen
|
2
4
|
module Adapter
|
3
5
|
# Adapter implementation for Mac OS X `FSEvents`.
|
@@ -10,6 +12,7 @@ module Listen
|
|
10
12
|
|
11
13
|
private
|
12
14
|
|
15
|
+
# NOTE: each directory gets a DIFFERENT callback!
|
13
16
|
def _configure(dir, &callback)
|
14
17
|
require 'rb-fsevent'
|
15
18
|
opts = { latency: options.latency }
|
@@ -20,8 +23,20 @@ module Listen
|
|
20
23
|
end
|
21
24
|
end
|
22
25
|
|
26
|
+
# NOTE: _run is called within a thread, so run every other
|
27
|
+
# worker in it's own thread
|
23
28
|
def _run
|
24
|
-
@workers.pop
|
29
|
+
first = @workers.pop
|
30
|
+
until @workers.empty?
|
31
|
+
Listen::Internals::ThreadPool.add do
|
32
|
+
begin
|
33
|
+
@workers.pop.run
|
34
|
+
rescue
|
35
|
+
_log_exception 'run() in extra thread(s) failed: %s: %s'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
first.run
|
25
40
|
end
|
26
41
|
|
27
42
|
def _process_event(dir, event)
|
data/lib/listen/adapter/tcp.rb
CHANGED
@@ -26,16 +26,18 @@ module Listen
|
|
26
26
|
@buffer = ''
|
27
27
|
async.run
|
28
28
|
rescue Celluloid::Task::TerminatedError
|
29
|
-
_log :debug, "TCP adapter was terminated: #{
|
29
|
+
_log :debug, "TCP adapter was terminated: #{$ERROR_INFO.inspect}"
|
30
30
|
rescue Errno::ECONNREFUSED
|
31
31
|
sleep 1
|
32
32
|
attempts -= 1
|
33
|
-
_log :warn, "TCP.start: #{
|
33
|
+
_log :warn, "TCP.start: #{$ERROR_INFO.inspect}"
|
34
34
|
retry if attempts > 0
|
35
|
-
_log :error,
|
35
|
+
_log :error, format('TCP.start: %s:%s', $ERROR_INFO.inspect,
|
36
|
+
$ERROR_POSITION * "\n")
|
36
37
|
raise
|
37
38
|
rescue
|
38
|
-
_log :error,
|
39
|
+
_log :error, format('TCP.start: %s:%s', $ERROR_INFO.inspect,
|
40
|
+
$ERROR_POSITION * "\n")
|
39
41
|
raise
|
40
42
|
end
|
41
43
|
|
@@ -65,7 +67,8 @@ module Listen
|
|
65
67
|
handle_message(message)
|
66
68
|
end
|
67
69
|
rescue
|
68
|
-
_log :error,
|
70
|
+
_log :error, format('TCP.handle_data crashed: %s:%s', $ERROR_INFO,
|
71
|
+
$ERROR_POSITION * "\n")
|
69
72
|
raise
|
70
73
|
end
|
71
74
|
|
@@ -7,10 +7,7 @@ module Listen
|
|
7
7
|
|
8
8
|
BUNDLER_DECLARE_GEM = <<-EOS.gsub(/^ {6}/, '')
|
9
9
|
Please add the following to your Gemfile to avoid polling for changes:
|
10
|
-
|
11
|
-
if RbConfig::CONFIG['target_os'] =~ /mswin|mingw|cygwin/i
|
12
|
-
gem 'wdm', '>= 0.1.0'
|
13
|
-
end
|
10
|
+
gem 'wdm', '>= 0.1.0' if Gem.win_platform?
|
14
11
|
EOS
|
15
12
|
|
16
13
|
def self.usable?
|
@@ -18,7 +15,9 @@ module Listen
|
|
18
15
|
require 'wdm'
|
19
16
|
true
|
20
17
|
rescue LoadError
|
21
|
-
_log :debug,
|
18
|
+
_log :debug, format('wdm - load failed: %s:%s', $ERROR_INFO,
|
19
|
+
$ERROR_POSITION * "\n")
|
20
|
+
|
22
21
|
Kernel.warn BUNDLER_DECLARE_GEM
|
23
22
|
false
|
24
23
|
end
|
@@ -82,7 +81,8 @@ module Listen
|
|
82
81
|
end
|
83
82
|
rescue
|
84
83
|
details = event.inspect
|
85
|
-
_log :error,
|
84
|
+
_log :error, format('wdm - callback (%): %s:%s', details, $ERROR_INFO,
|
85
|
+
$ERROR_POSITION * "\n")
|
86
86
|
raise
|
87
87
|
end
|
88
88
|
|
data/lib/listen/change.rb
CHANGED
@@ -43,9 +43,10 @@ module Listen
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
rescue Celluloid::Task::TerminatedError
|
46
|
-
_log :debug, "Change#change was terminated: #{
|
46
|
+
_log :debug, "Change#change was terminated: #{$ERROR_INFO.inspect}"
|
47
47
|
rescue RuntimeError
|
48
|
-
_log :error,
|
48
|
+
_log :error, format('Change#change crashed %s:%s', $ERROR_INFO.inspect,
|
49
|
+
$ERROR_POSITION * "\n")
|
49
50
|
raise
|
50
51
|
end
|
51
52
|
|
data/lib/listen/cli.rb
CHANGED
data/lib/listen/directory.rb
CHANGED
@@ -13,16 +13,10 @@ module Listen
|
|
13
13
|
path = dir + rel_path
|
14
14
|
current = Set.new(path.children)
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
else
|
22
|
-
_log(:debug) do
|
23
|
-
"Scanning: #{rel_path}: #{options.inspect}"\
|
24
|
-
" [#{previous.inspect}] -> (#{current.inspect})"
|
25
|
-
end
|
16
|
+
_log(:debug) do
|
17
|
+
format('%s: %s(%s): %s -> %s',
|
18
|
+
(options[:silence] ? 'Recording' : 'Scanning'),
|
19
|
+
rel_path, options.inspect, previous.inspect, current.inspect)
|
26
20
|
end
|
27
21
|
|
28
22
|
current.each do |full_path|
|
@@ -46,7 +40,9 @@ module Listen
|
|
46
40
|
_async_changes(dir, path, queue, previous, options)
|
47
41
|
_change(queue, :file, dir, rel_path, options)
|
48
42
|
rescue
|
49
|
-
_log(:warn)
|
43
|
+
_log(:warn) do
|
44
|
+
format('scan DIED: %s:%s', $ERROR_INFO, $ERROR_POSITION * "\n")
|
45
|
+
end
|
50
46
|
raise
|
51
47
|
end
|
52
48
|
|
data/lib/listen/file.rb
CHANGED
@@ -23,52 +23,46 @@ module Listen
|
|
23
23
|
return :modified
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
# Check if change happened within 1 second (maybe it's even
|
29
|
-
# too much, e.g. 0.3-0.5 could be sufficient).
|
30
|
-
#
|
31
|
-
# With rb-fsevent, there's a (configurable) latency between
|
32
|
-
# when file was changed and when the event was triggered.
|
33
|
-
#
|
34
|
-
# If a file is saved at ???14.998, by the time the event is
|
35
|
-
# actually received by Listen, the time could already be e.g.
|
36
|
-
# ???15.7.
|
37
|
-
#
|
38
|
-
# And since Darwin adapter uses directory scanning, the file
|
39
|
-
# mtime may be the same (e.g. file was changed at ???14.001,
|
40
|
-
# then at ???14.998, but the fstat time would be ???14.0 in
|
41
|
-
# both cases).
|
42
|
-
#
|
43
|
-
# If change happend at ???14.999997, the mtime is 14.0, so for
|
44
|
-
# an mtime=???14.0 we assume it could even be almost ???15.0
|
45
|
-
#
|
46
|
-
# So if Time.now.to_f is ???15.999998 and stat reports mtime
|
47
|
-
# at ???14.0, then event was due to that file'd change when:
|
48
|
-
#
|
49
|
-
# ???15.999997 - ???14.999998 < 1.0s
|
50
|
-
#
|
51
|
-
# So the "2" is "1 + 1" (1s to cover rb-fsevent latency +
|
52
|
-
# 1s maximum difference between real mtime and that recorded
|
53
|
-
# in the file system)
|
54
|
-
#
|
55
|
-
if data[:mtime].to_i + 2 > Time.now.to_f
|
56
|
-
begin
|
57
|
-
md5 = Digest::MD5.file(path).digest
|
58
|
-
record.async.update_file(dir, rel_path, data.merge(md5: md5))
|
59
|
-
:modified if record_data[:md5] && md5 != record_data[:md5]
|
26
|
+
return if /1|true/ =~ ENV['LISTEN_GEM_DISABLE_HASHING']
|
27
|
+
return unless self.inaccurate_mac_time?(lstat)
|
60
28
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
29
|
+
# Check if change happened within 1 second (maybe it's even
|
30
|
+
# too much, e.g. 0.3-0.5 could be sufficient).
|
31
|
+
#
|
32
|
+
# With rb-fsevent, there's a (configurable) latency between
|
33
|
+
# when file was changed and when the event was triggered.
|
34
|
+
#
|
35
|
+
# If a file is saved at ???14.998, by the time the event is
|
36
|
+
# actually received by Listen, the time could already be e.g.
|
37
|
+
# ???15.7.
|
38
|
+
#
|
39
|
+
# And since Darwin adapter uses directory scanning, the file
|
40
|
+
# mtime may be the same (e.g. file was changed at ???14.001,
|
41
|
+
# then at ???14.998, but the fstat time would be ???14.0 in
|
42
|
+
# both cases).
|
43
|
+
#
|
44
|
+
# If change happend at ???14.999997, the mtime is 14.0, so for
|
45
|
+
# an mtime=???14.0 we assume it could even be almost ???15.0
|
46
|
+
#
|
47
|
+
# So if Time.now.to_f is ???15.999998 and stat reports mtime
|
48
|
+
# at ???14.0, then event was due to that file'd change when:
|
49
|
+
#
|
50
|
+
# ???15.999997 - ???14.999998 < 1.0s
|
51
|
+
#
|
52
|
+
# So the "2" is "1 + 1" (1s to cover rb-fsevent latency +
|
53
|
+
# 1s maximum difference between real mtime and that recorded
|
54
|
+
# in the file system)
|
55
|
+
#
|
56
|
+
return if data[:mtime].to_i + 2 <= Time.now.to_f
|
57
|
+
|
58
|
+
md5 = Digest::MD5.file(path).digest
|
59
|
+
record.async.update_file(dir, rel_path, data.merge(md5: md5))
|
60
|
+
:modified if record_data[:md5] && md5 != record_data[:md5]
|
67
61
|
rescue SystemCallError
|
68
62
|
record.async.unset_path(dir, rel_path)
|
69
63
|
:removed
|
70
64
|
rescue
|
71
|
-
Celluloid::Logger.debug "lstat failed for: #{rel_path} (#{
|
65
|
+
Celluloid::Logger.debug "lstat failed for: #{rel_path} (#{$ERROR_INFO})"
|
72
66
|
raise
|
73
67
|
end
|
74
68
|
|