Skip to content

Commit

Permalink
Merge pull request #318 from guard/listen_3x_proposal
Browse files Browse the repository at this point in the history
Listen 3x proposal
  • Loading branch information
e2 committed Jun 26, 2015
2 parents 9ee289f + 0696aa0 commit 457c3cb
Show file tree
Hide file tree
Showing 65 changed files with 2,733 additions and 2,277 deletions.
5 changes: 2 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
language: ruby
bundler_args: --without development
rvm:
- 1.9.3
- 2.2.0
- 2.2.2
- jruby
- rbx-2
matrix:
Expand All @@ -18,5 +17,5 @@ os:
- linux
- osx
env:
- LISTEN_TESTS_DEFAULT_LAG=0.8 LISTEN_TESTS_DEFAULT_TCP_LAG=1.2
- LISTEN_TESTS_DEFAULT_LAG=0.8
sudo: false
15 changes: 9 additions & 6 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
source 'https://rubygems.org'

gemspec development_group: :gem_build_tools
# Create this file to use pristine/installed version of Listen for development
use_installed = "./use_installed_guard"
if File.exist?(use_installed)
STDERR.puts "WARNING: using installed version of Listen for development" \
" (remove #{use_installed} file to use local version)"
else
gemspec development_group: :gem_build_tools
end

require 'rbconfig'

case RbConfig::CONFIG['target_os']
when /mswin|mingw|cygwin/i
gem 'wdm', '>= 0.1.0'
Kernel.warn 'NOTE: Celluloid may not work properly on your platform'
when /bsd|dragonfly/i
gem 'rb-kqueue', '>= 0.2'
end

group :test do
gem 'celluloid', github: 'celluloid/celluloid', branch: '0-16-stable'
gem 'celluloid-io', '>= 0.15.0'
gem 'rake'
gem 'rspec', '~> 3.2'
gem 'rspec-retry'
gem 'rspec', '~> 3.3'
gem 'coveralls'
end

Expand Down
14 changes: 12 additions & 2 deletions Guardfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
ignore(%r{spec/\.fixtures/})

group :specs, halt_on_fail: true do
guard :rspec, cmd: 'bundle exec rspec', failed_mode: :keep do
watch(%r{^spec/.+_spec\.rb$})
guard :rspec, cmd: 'bundle exec rspec -t ~acceptance', failed_mode: :keep, all_after_pass: true do
watch(%r{^spec/lib/.+_spec\.rb$})
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
watch(%r{^spec/support/*}) { 'spec' }
watch('spec/spec_helper.rb') { 'spec' }
Expand All @@ -13,4 +13,14 @@ group :specs, halt_on_fail: true do
watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
watch(%r{(?:.+/)?\.rubocop_todo\.yml$}) { |m| File.dirname(m[0]) }
end

# TODO: guard rspec should have a configurable file for this to work
# TODO: also split up Rakefile
guard :rspec, cmd: 'bundle exec rspec -t acceptance', failed_mode: :keep, all_after_pass: true do
watch(%r{^spec/lib/.+_spec\.rb$})
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
watch(%r{^spec/support/*}) { 'spec' }
watch('spec/spec_helper.rb') { 'spec' }
watch(%r{^spec/acceptance/.+_spec\.rb$})
end
end
46 changes: 3 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ Make sure you know these few basic tricks: https://github.com/guard/listen/wiki/
* Detects file modification, addition and removal.
* You can watch multiple directories.
* Regexp-patterns for ignoring paths for more accuracy and speed
* Forwarding file events over TCP, [more info](#forwarding-file-events-over-tcp) below.
* Increased change detection accuracy on OS X HFS and VFAT volumes.
* Tested on MRI Ruby environments (1.9+ only) via [Travis CI](https://travis-ci.org/guard/listen),

Expand All @@ -29,6 +28,8 @@ Please note that:
- Specs suite on JRuby and Rubinius aren't reliable on Travis CI, but should work.
- Windows and \*BSD adapter aren't continuously and automaticaly tested.

NOTE: TCP functionality has been moved to a separate gem (listen-server and listen-client)

## Pending features / issues

* symlinked directories aren't fully transparent yet: https://github.com/guard/listen/issues/279
Expand Down Expand Up @@ -166,7 +167,7 @@ force_polling: true # Force the use of the polling a
relative: false # Whether changes should be relative to current dir or not
# default: false

debug: true # Enable Celluloid logger
debug: true # Enable Listen logger
# default: false

polling_fallback_message: 'custom message' # Set a custom polling fallback message (or disable it with false)
Expand Down Expand Up @@ -247,47 +248,6 @@ Also, if the directories you're watching contain many files, make sure you're:

When in doubt, LISTEN_GEM_DEBUGGING=2 can help discover the actual events and time they happened.

## Forwarding file events over TCP

Listen is capable of forwarding file events over the network using a messaging protocol. This can be useful for virtualized development environments when file events are unavailable, as is the case with shared folders in VMs.

[Vagrant](https://github.com/mitchellh/vagrant) uses Listen in it's rsync-auto mode to solve this issue.

To broadcast events over TCP programmatically, use the `forward_to` option with an address - just a port or a hostname/port combination:

```ruby
listener = Listen.to 'path/to/app', forward_to: '10.0.0.2:4000' do |modified, added, removed|
# After broadcasting the changes to any connected recipients,
# this block will still be called
end
listener.start
sleep
```

As a convenience, the `listen` script is supplied which listens to a directory and forwards the events to a network address

```bash
listen -f "10.0.0.2:4000" # changes in current directory are sent as absolute paths
listen -r -f "10.0.0.2:4000" # changes in current directory are sent as relative paths
listen -v -d "/projects/my_project" -f "10.0.0.2:4000" # changes in given directory are also shown
```

*NOTE: if you are using a gem like `guard` and the paths on host and guest are not exactly the same, you'll generally want to use the `-r` option for relative paths*

To connect to a broadcasting listener as a recipient, specify its address using `Listen.on`:

```ruby
listener = Listen.on '10.0.0.2:4000' do |modified, added, removed|
# This block will be called
end
listener.start
sleep
```

### Security considerations

Since file events potentially expose sensitive information, care must be taken when specifying the broadcaster address. It is recommended to **always** specify a hostname and make sure it is as specific as possible to reduce any undesirable eavesdropping.

## Development

* Documentation hosted at [RubyDoc](http://rubydoc.info/github/guard/listen/master/frames).
Expand Down
59 changes: 19 additions & 40 deletions lib/listen.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
require 'celluloid'
require 'logger'
require 'listen/logger'
require 'listen/listener'

require 'listen/internals/thread_pool'

# Always set up logging by default first time file is required
#
# NOTE: If you need to clear the logger completely, do so *after*
# requiring this file. If you need to set a custom logger,
# require the listen/logger file and set the logger before requiring
# this file.
Listen.setup_default_logger_if_unset

# Won't print anything by default because of level - unless you've set
# LISTEN_GEM_DEBUGGING or provided your own logger with a high enough level
Listen::Logger.info "Listen loglevel set to: #{Listen.logger.level}"
Listen::Logger.info "Listen version: #{Listen::VERSION}"

module Listen
class << self
# Listens to file system modifications on a either single directory or
# multiple directories.
#
# When :forward_to is specified, this listener will broadcast modifications
# over TCP.
#
# @param (see Listen::Listener#new)
#
# @yield [modified, added, removed] the changed files
Expand All @@ -21,18 +32,12 @@ class << self
# @return [Listen::Listener] the listener
#
def to(*args, &block)
Celluloid.boot unless Celluloid.running?
options = args.last.is_a?(Hash) ? args.last : {}
target = options.delete(:forward_to)
args = ([target, :broadcaster] + args) if target
_add_listener(*args, &block)
@listeners ||= []
Listener.new(*args, &block).tap do |listener|
@listeners << listener
end
end

# Stop all listeners & Celluloid
#
# Use it for testing purpose or when you are sure that Celluloid could be
# ended.
#
# This is used by the `listen` binary to handle Ctrl-C
#
def stop
Expand All @@ -45,32 +50,6 @@ def stop
listener.stop
end
@listeners = nil

Celluloid.shutdown
end

# Listens to file system modifications broadcast over TCP.
#
# @param [String/Fixnum] target to listen on (hostname:port or port)
#
# @yield [modified, added, removed] the changed files
# @yieldparam [Array<String>] modified the list of modified files
# @yieldparam [Array<String>] added the list of added files
# @yieldparam [Array<String>] removed the list of removed files
#
# @return [Listen::Listener] the listener
#
def on(target, *args, &block)
_add_listener(target, :recipient, *args, &block)
end

private

def _add_listener(*args, &block)
@listeners ||= []
Listener.new(*args, &block).tap do |listener|
@listeners << listener
end
end
end
end
4 changes: 1 addition & 3 deletions lib/listen/adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ module Adapter
'Learn more at https://github.com/guard/listen#listen-adapters.'

def self.select(options = {})
_log :debug, 'Adapter: considering TCP ...'
return TCP if options[:force_tcp]
_log :debug, 'Adapter: considering polling ...'
return Polling if options[:force_polling]
_log :debug, 'Adapter: considering optimized backend...'
Expand All @@ -39,7 +37,7 @@ def self._warn_polling_fallback(options)
end

def self._log(type, message)
Celluloid::Logger.send(type, message)
Listen::Logger.send(type, message)
end
end
end
Loading

0 comments on commit 457c3cb

Please sign in to comment.