Skip to content

Commit

Permalink
WIP: Use NIO.2 WatchService for JRuby
Browse files Browse the repository at this point in the history
  • Loading branch information
floehopper committed Aug 3, 2019
1 parent dc1e798 commit 357563b
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/listen/adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
require 'listen/adapter/linux'
require 'listen/adapter/polling'
require 'listen/adapter/windows'
require 'listen/adapter/jruby'

module Listen
module Adapter
OPTIMIZED_ADAPTERS = [Darwin, Linux, BSD, Windows].freeze
OPTIMIZED_ADAPTERS = [Darwin, Linux, BSD, Windows, Jruby].freeze
POLLING_FALLBACK_MESSAGE = 'Listen will be polling for changes.'\
'Learn more at https://github.com/guard/listen#listen-adapters.'.freeze

Expand Down
55 changes: 55 additions & 0 deletions lib/listen/adapter/jruby.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module Listen
module Adapter
# @see https://docs.oracle.com/javase/tutorial/essential/io/notification.html
class Jruby < Base
def self.usable?
RUBY_ENGINE == 'jruby'
end

private

def _configure(directory, &callback)
require 'java'
java_import 'java.nio.file.FileSystems'
java_import 'java.nio.file.Paths'
java_import 'java.nio.file.StandardWatchEventKinds'

event_kinds = [
StandardWatchEventKinds::ENTRY_CREATE,
StandardWatchEventKinds::ENTRY_MODIFY,
StandardWatchEventKinds::ENTRY_DELETE
]

@watcher ||= FileSystems.getDefault.newWatchService
@keys ||= {}
path = Paths.get(directory.to_s)
key = path.register(@watcher, *event_kinds)
@keys[key] = path
end

def _run
loop do
key = @watcher.take
dir = @keys[key]
next if dir.nil?
key.pollEvents.each do |event|
kind = event.kind
next if kind == StandardWatchEventKinds::OVERFLOW
name = event.context
child = dir.resolve(name)
pathname = Pathname.new(child.to_s).dirname
_queue_change(:dir, pathname, '.', recursive: true)
valid = key.reset
unless valid
@keys.delete(key)
break if @keys.empty?
end
end
end
end

def _process_event(dir, event)
end
end
end
end
11 changes: 11 additions & 0 deletions spec/lib/listen/adapter/jruby_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
RSpec.describe Listen::Adapter::Jruby do
describe 'class' do
subject { described_class }

if jruby?
it { should be_usable }
else
it { should_not be_usable }
end
end
end
7 changes: 7 additions & 0 deletions spec/lib/listen/adapter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
allow(Listen::Adapter::Darwin).to receive(:usable?) { false }
allow(Listen::Adapter::Linux).to receive(:usable?) { false }
allow(Listen::Adapter::Windows).to receive(:usable?) { false }
allow(Listen::Adapter::Jruby).to receive(:usable?) { false }
end

describe '.select' do
Expand Down Expand Up @@ -37,6 +38,12 @@
expect(klass).to eq Listen::Adapter::Windows
end

it 'returns JRuby adapter when usable' do
allow(Listen::Adapter::Jruby).to receive(:usable?) { true }
klass = Listen::Adapter.select
expect(klass).to eq Listen::Adapter::Jruby
end

context 'no usable adapters' do
before { allow(Kernel).to receive(:warn) }

Expand Down
4 changes: 4 additions & 0 deletions spec/support/platform_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ def bsd?
def windows?
RbConfig::CONFIG['target_os'] =~ /mswin|mingw|cygwin/i
end

def jruby?
RUBY_ENGINE == 'jruby'
end

0 comments on commit 357563b

Please sign in to comment.