listen 3.3.3 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6e8a5f611b09b7689da35117369be07e2cb74ed77575dc7d894c12629767ad82
4
- data.tar.gz: c7995d9785eb3202fa13528489a0c48e54c70fc201c750cb885777d36151b316
3
+ metadata.gz: 393d712be43ee070ac7d14a4ddc090176c7f388ae2f2a7e447f674fc8875f27f
4
+ data.tar.gz: b4dfff00d893121350cb41362425a52ae4c78af20431b0567071a381d9216786
5
5
  SHA512:
6
- metadata.gz: fb0d331747afe760ab96a3eecf20d041e1e9fec0a2c49b678289fe56250c2a357a4826c9d4c9da38c9db7f819e7d61f6b9f5245c23a34c4eb9f77868abde2ec0
7
- data.tar.gz: 3c7d8b1f91224ea4a10b4f039e334fbb85c0eae14996bf2df9c32a9487325f94a5e1d1ce87abefa23dce2f50b0bac2069950d05ec1f561552fb9c8493c31fd83
6
+ metadata.gz: 7c7e46108e8cc30fc15289e12bedf0866ea6ef41a6798f701e16f265205ffee95a23b4526b098ae26ac910c942084d34280de31878e696e93f4d14a8f674c3ec
7
+ data.tar.gz: 3edd0902f5833038beb0b8e33b4f6f4933bea1659d51b68dbbc9a5abc63bf3ee3edd25a56309d16cd6acffead3e3be05f6ebc4d2895c893e70baff941015fcc1
data/README.md CHANGED
@@ -22,7 +22,7 @@ The `listen` gem listens to file modifications and notifies you about the change
22
22
 
23
23
  * Limited support for symlinked directories ([#279](https://github.com/guard/listen/issues/279)):
24
24
  * Symlinks are always followed ([#25](https://github.com/guard/listen/issues/25)).
25
- * Symlinked directories pointing within a watched directory are not supported ([#273](https://github.com/guard/listen/pull/273)- see [Duplicate directory errors](https://github.com/guard/listen/wiki/Duplicate-directory-errors)).
25
+ * Symlinked directories pointing within a watched directory are not supported ([#273](https://github.com/guard/listen/pull/273).
26
26
  * No directory/adapter-specific configuration options.
27
27
  * Support for plugins planned for future.
28
28
  * TCP functionality was removed in `listen` [3.0.0](https://github.com/guard/listen/releases/tag/v3.0.0) ([#319](https://github.com/guard/listen/issues/319), [#218](https://github.com/guard/listen/issues/218)). There are plans to extract this feature to separate gems ([#258](https://github.com/guard/listen/issues/258)), until this is finished, you can use by locking the `listen` gem to version `'~> 2.10'`.
@@ -40,7 +40,7 @@ Pull requests or help is very welcome for these.
40
40
  The simplest way to install `listen` is to use [Bundler](http://bundler.io).
41
41
 
42
42
  ```ruby
43
- gem 'listen', '~> 3.3' # NOTE: for TCP functionality, use '~> 2.10' for now
43
+ gem 'listen'
44
44
  ```
45
45
 
46
46
  ## Complete Example
@@ -240,7 +240,7 @@ If you are on Windows, it's recommended to use the [`wdm`](https://github.com/Ma
240
240
  Please add the following to your Gemfile:
241
241
 
242
242
  ```ruby
243
- gem 'wdm', '>= 0.1.0' if Gem.win_platform?
243
+ gem 'wdm', '>= 0.1.0', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
244
244
  ```
245
245
 
246
246
  ### On \*BSD
@@ -259,7 +259,82 @@ end
259
259
 
260
260
  ### Getting the [polling fallback message](#options)?
261
261
 
262
- Please visit the [installation section of the Listen WIKI](https://github.com/guard/listen/wiki#installation) for more information and options for potential fixes.
262
+ If you see:
263
+ ```
264
+ Listen will be polling for changes.
265
+ ```
266
+
267
+ This means the Listen gem can’t find an optimized adapter. Typically this is caused by:
268
+
269
+ - You’re on Windows and WDM gem isn’t installed.
270
+ - You’re running the app without Bundler or RubyGems.
271
+ - Using Sass which includes an ancient (the “dinosaur” type of ancient) version of the Listen gem.
272
+
273
+ Possible solutions:
274
+
275
+ 1. Suppress the message by using the :force_polling option. Or, you could just ignore the message since it’s harmless.
276
+ 2. Windows users: Install the WDM gem.
277
+ 3. Upgrade Ruby (use RubyInstaller for Windows or RVM/rbenv for Mac) and RubyGems.
278
+ 3. Run your apps using Bundler.
279
+ 4. Sass users: Install the latest version of Listen and try again.
280
+
281
+ #### Simplified Bundler and Sass example
282
+ Create a Gemfile with these lines:
283
+ ```
284
+ source 'https://rubygems.org'
285
+ gem 'listen'
286
+ gem 'sass'
287
+ ```
288
+ Next, use Bundler to update gems:
289
+ ```
290
+ $ bundle update
291
+ $ bundle exec sass --watch # ... or whatever app is using Listen.
292
+ ```
293
+
294
+ ### Increasing the amount of inotify watchers
295
+
296
+ If you are running Debian, RedHat, or another similar Linux distribution, run the following in a terminal:
297
+ ```
298
+ $ sudo sh -c "echo fs.inotify.max_user_watches=524288 >> /etc/sysctl.conf"
299
+ $ sudo sysctl -p
300
+ ```
301
+ If you are running ArchLinux, search the `/etc/sysctl.d/` directory for config files with the setting:
302
+ ```
303
+ $ grep -H -s "fs.inotify.max_user_watches" /etc/sysctl.d/*
304
+ /etc/sysctl.d/40-max_user_watches.conf:fs.inotify.max_user_watches=100000
305
+ ```
306
+ Then change the setting in the file you found above to a higher value (see [here](https://www.archlinux.org/news/deprecation-of-etcsysctlconf/) for why):
307
+ ```
308
+ $ sudo sh -c "echo fs.inotify.max_user_watches=524288 > /etc/sysctl.d/40-max-user-watches.conf"
309
+ $ sudo sysctl --system
310
+ ```
311
+
312
+ #### The technical details
313
+ Listen uses `inotify` by default on Linux to monitor directories for changes.
314
+ It's not uncommon to encounter a system limit on the number of files you can monitor.
315
+ For example, Ubuntu Lucid's (64bit) `inotify` limit is set to 8192.
316
+
317
+ You can get your current inotify file watch limit by executing:
318
+ ```
319
+ $ cat /proc/sys/fs/inotify/max_user_watches
320
+ ```
321
+ When this limit is not enough to monitor all files inside a directory, the limit must be increased for Listen to work properly.
322
+
323
+ You can set a new limit temporarily with:
324
+ ```
325
+ $ sudo sysctl fs.inotify.max_user_watches=524288
326
+ $ sudo sysctl -p
327
+ ```
328
+ If you like to make your limit permanent, use:
329
+ ```
330
+ $ sudo sh -c "echo fs.inotify.max_user_watches=524288 >> /etc/sysctl.conf"
331
+ $ sudo sysctl -p
332
+ ```
333
+ You may also need to pay attention to the values of `max_queued_events` and `max_user_instances` if Listen keeps on complaining.
334
+
335
+ #### More info
336
+ Man page for [inotify(7)](https://linux.die.net/man/7/inotify).
337
+ Blog post: [limit of inotify](https://blog.sorah.jp/2012/01/24/inotify-limitation).
263
338
 
264
339
  ### Issues and Troubleshooting
265
340
 
@@ -267,7 +342,35 @@ If the gem doesn't work as expected, start by setting `LISTEN_GEM_DEBUGGING=debu
267
342
 
268
343
  *NOTE: without providing the output after setting the `LISTEN_GEM_DEBUGGING=debug` environment variable, it is usually impossible to guess why `listen` is not working as expected.*
269
344
 
270
- See [TROUBLESHOOTING](https://github.com/guard/listen/wiki/Troubleshooting)
345
+ #### 3 steps before you start diagnosing problems
346
+ These 3 steps will:
347
+
348
+ - help quickly troubleshoot obscure problems (trust me, most of them are obscure)
349
+ - help quickly identify the area of the problem (a full list is below)
350
+ - help you get familiar with listen's diagnostic mode (it really comes in handy, trust me)
351
+ - help you create relevant output before you submit an issue (so we can respond with answers instead of tons of questions)
352
+
353
+ Step 1 - The most important option in Listen
354
+ For effective troubleshooting set the `LISTEN_GEM_DEBUGGING=info` variable before starting `listen`.
355
+
356
+ Step 2 - Verify polling works
357
+ Polling has to work ... or something is really wrong (and we need to know that before anything else).
358
+
359
+ (see force_polling option).
360
+
361
+ After starting `listen`, you should see something like:
362
+ ```
363
+ INFO -- : Record.build(): 0.06773114204406738 seconds
364
+ ```
365
+ Step 3 - Trigger some changes directly without using editors or apps
366
+ Make changes e.g. touch foo or echo "a" >> foo (for troubleshooting, avoid using an editor which could generate too many misleading events).
367
+
368
+ You should see something like:
369
+ ```
370
+ INFO -- : listen: raw changes: [[:added, "/home/me/foo"]]
371
+ INFO -- : listen: final changes: {:modified=>[], :added=>["/home/me/foo"], :removed=>[]}
372
+ ```
373
+ "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).
271
374
 
272
375
  ## Performance
273
376
 
@@ -289,7 +392,11 @@ Also, if the directories you're watching contain many files, make sure you're:
289
392
 
290
393
  When in doubt, `LISTEN_GEM_DEBUGGING=debug` can help discover the actual events and time they happened.
291
394
 
292
- See also [Tips and Techniques](https://github.com/guard/listen/wiki/Tips-and-Techniques).
395
+ ## Tips and Techniques
396
+ - Watch only directories you're interested in.
397
+ - Set your editor to save quickly (e.g. without backup files, without atomic-save)
398
+ - Tweak the `:latency` and `:wait_for_delay` options until you get good results (see [options](#options)).
399
+ - Add `:ignore` rules to silence all events you don't care about (reduces a lot of noise, especially if you use it on directories)
293
400
 
294
401
  ## Development
295
402
 
@@ -93,9 +93,9 @@ module Listen
93
93
  end
94
94
 
95
95
  def _timed(title)
96
- start = Time.now.to_f
96
+ start = MonotonicTime.now
97
97
  yield
98
- diff = Time.now.to_f - start
98
+ diff = MonotonicTime.now - start
99
99
  Listen.logger.info format('%s: %.05f seconds', title, diff)
100
100
  rescue
101
101
  Listen.logger.warn "#{title} crashed: #{$ERROR_INFO.inspect}"
@@ -22,7 +22,7 @@ module Listen
22
22
  private
23
23
 
24
24
  WIKI_URL = 'https://github.com/guard/listen'\
25
- '/wiki/Increasing-the-amount-of-inotify-watchers'
25
+ '/blob/master/README.md#increasing-the-amount-of-inotify-watchers'
26
26
 
27
27
  INOTIFY_LIMIT_MESSAGE = <<-EOS.gsub(/^\s*/, '')
28
28
  FATAL: Listen error: unable to monitor directories for changes.
@@ -21,12 +21,13 @@ module Listen
21
21
 
22
22
  def _run
23
23
  loop do
24
- start = Time.now.to_f
24
+ start = MonotonicTime.now
25
25
  @polling_callbacks.each do |callback|
26
26
  callback.call(nil)
27
- nap_time = options.latency - (Time.now.to_f - start)
28
- # TODO: warn if nap_time is negative (polling too slow)
29
- sleep(nap_time) if nap_time > 0
27
+ if (nap_time = options.latency - (MonotonicTime.now - start)) > 0
28
+ # TODO: warn if nap_time is negative (polling too slow)
29
+ sleep(nap_time)
30
+ end
30
31
  end
31
32
  end
32
33
  end
@@ -28,10 +28,6 @@ module Listen
28
28
  @block&.call(*args)
29
29
  end
30
30
 
31
- def timestamp
32
- Time.now.to_f
33
- end
34
-
35
31
  def callable?
36
32
  @block
37
33
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'listen/monotonic_time'
4
+
3
5
  module Listen
4
6
  module Event
5
7
  class Processor
@@ -33,7 +35,7 @@ module Listen
33
35
 
34
36
  def _wait_until_events_calm_down
35
37
  loop do
36
- now = _timestamp
38
+ now = MonotonicTime.now
37
39
 
38
40
  # Assure there's at least latency between callbacks to allow
39
41
  # for accumulating changes
@@ -70,7 +72,7 @@ module Listen
70
72
  end
71
73
 
72
74
  def _remember_time_of_first_unprocessed_event
73
- @_remember_time_of_first_unprocessed_event ||= _timestamp
75
+ @_remember_time_of_first_unprocessed_event ||= MonotonicTime.now
74
76
  end
75
77
 
76
78
  def _reset_no_unprocessed_events
@@ -85,7 +87,7 @@ module Listen
85
87
  # returns the event or `nil` when the event_queue is closed
86
88
  def _wait_until_events
87
89
  config.event_queue.pop.tap do |_event|
88
- @_remember_time_of_first_unprocessed_event ||= _timestamp
90
+ @_remember_time_of_first_unprocessed_event ||= MonotonicTime.now
89
91
  end
90
92
  end
91
93
 
@@ -96,10 +98,6 @@ module Listen
96
98
  end
97
99
  end
98
100
 
99
- def _timestamp
100
- config.timestamp
101
- end
102
-
103
101
  # for easier testing without sleep loop
104
102
  def _process_changes(event)
105
103
  _reset_no_unprocessed_events
@@ -113,13 +111,13 @@ module Listen
113
111
  result = [hash[:modified], hash[:added], hash[:removed]]
114
112
  return if result.all?(&:empty?)
115
113
 
116
- block_start = _timestamp
114
+ block_start = MonotonicTime.now
117
115
  exception_note = " (exception)"
118
116
  ::Listen::Thread.rescue_and_log('_process_changes') do
119
117
  config.call(*result)
120
118
  exception_note = nil
121
119
  end
122
- Listen.logger.debug "Callback#{exception_note} took #{_timestamp - block_start} sec"
120
+ Listen.logger.debug "Callback#{exception_note} took #{MonotonicTime.now - block_start} sec"
123
121
  end
124
122
 
125
123
  attr_reader :config
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Listen
4
+ module MonotonicTime
5
+ class << self
6
+ if defined?(Process::CLOCK_MONOTONIC)
7
+
8
+ def now
9
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
10
+ end
11
+
12
+ elsif defined?(Process::CLOCK_MONOTONIC_RAW)
13
+
14
+ def now
15
+ Process.clock_gettime(Process::CLOCK_MONOTONIC_RAW)
16
+ end
17
+
18
+ else
19
+
20
+ def now
21
+ Time.now.to_f
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -45,10 +45,11 @@ module Listen
45
45
  end
46
46
 
47
47
  def dir_entries(rel_path)
48
- subtree = if [nil, '', '.'].include? rel_path.to_s
48
+ subtree = if ['', '.'].include? rel_path.to_s
49
49
  @tree
50
50
  else
51
- _sub_tree(rel_path)
51
+ @tree[rel_path.to_s] ||= _auto_hash
52
+ @tree[rel_path.to_s]
52
53
  end
53
54
 
54
55
  subtree.transform_values do |values|
@@ -57,19 +58,6 @@ module Listen
57
58
  end
58
59
  end
59
60
 
60
- def _sub_tree(rel_path)
61
- @tree.each_with_object({}) do |(path, meta), result|
62
- next unless path.start_with?(rel_path)
63
-
64
- if path == rel_path
65
- result.merge!(meta)
66
- else
67
- sub_path = path.sub(%r{\A#{rel_path}/?}, '')
68
- result[sub_path] = meta
69
- end
70
- end
71
- end
72
-
73
61
  def build
74
62
  @tree = _auto_hash
75
63
  # TODO: test with a file name given
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Listen
4
- VERSION = '3.3.3'
4
+ VERSION = '3.4.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: listen
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.3
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thibaud Guillaume-Gentil
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-30 00:00:00.000000000 Z
11
+ date: 2020-12-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rb-fsevent
@@ -85,6 +85,7 @@ files:
85
85
  - lib/listen/listener.rb
86
86
  - lib/listen/listener/config.rb
87
87
  - lib/listen/logger.rb
88
+ - lib/listen/monotonic_time.rb
88
89
  - lib/listen/options.rb
89
90
  - lib/listen/queue_optimizer.rb
90
91
  - lib/listen/record.rb
@@ -101,9 +102,9 @@ metadata:
101
102
  allowed_push_host: https://rubygems.org
102
103
  bug_tracker_uri: https://github.com/guard/listen/issues
103
104
  changelog_uri: https://github.com/guard/listen/releases
104
- documentation_uri: https://www.rubydoc.info/gems/listen/3.3.3
105
+ documentation_uri: https://www.rubydoc.info/gems/listen/3.4.0
105
106
  homepage_uri: https://github.com/guard/listen
106
- source_code_uri: https://github.com/guard/listen/tree/v3.3.3
107
+ source_code_uri: https://github.com/guard/listen/tree/v3.4.0
107
108
  wiki_uri: https://github.com/guard/listen/wiki
108
109
  post_install_message:
109
110
  rdoc_options: []