listen 2.10.1 → 3.0.0

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.
@@ -1,88 +0,0 @@
1
- require 'celluloid/io'
2
-
3
- require 'listen/tcp/message'
4
-
5
- module Listen
6
- module Adapter
7
- # Adapter to receive file system modifications over TCP
8
- class TCP < Base
9
- OS_REGEXP = // # match any
10
-
11
- include Celluloid::IO
12
- finalizer :finalize
13
-
14
- DEFAULTS = {
15
- host: 'localhost',
16
- port: '4000'
17
- }
18
-
19
- attr_reader :buffer, :socket
20
-
21
- # Initializes and starts a Celluloid::IO-powered TCP-recipient
22
- def start
23
- attempts ||= 3
24
- _log :info, "TCP: opening socket #{options.host}:#{options.port}"
25
- @socket = TCPSocket.new(options.host, options.port)
26
- @buffer = ''
27
- async.run
28
- rescue Celluloid::Task::TerminatedError
29
- _log :debug, "TCP adapter was terminated: #{$ERROR_INFO.inspect}"
30
- rescue Errno::ECONNREFUSED
31
- sleep 1
32
- attempts -= 1
33
- _log :warn, "TCP.start: #{$ERROR_INFO.inspect}"
34
- retry if attempts > 0
35
- _log :error, format('TCP.start: %s:%s', $ERROR_INFO.inspect,
36
- $ERROR_POSITION * "\n")
37
- raise
38
- rescue
39
- _log :error, format('TCP.start: %s:%s', $ERROR_INFO.inspect,
40
- $ERROR_POSITION * "\n")
41
- raise
42
- end
43
-
44
- # Cleans up buffer and socket
45
- def finalize
46
- @buffer = nil
47
- return unless @socket
48
-
49
- @socket.close
50
- @socket = nil
51
- end
52
-
53
- # Number of bytes to receive at a time
54
- RECEIVE_WINDOW = 1024
55
-
56
- # Continuously receive and asynchronously handle data
57
- def run
58
- while (data = @socket.recv(RECEIVE_WINDOW))
59
- async.handle_data(data)
60
- end
61
- end
62
-
63
- # Buffers incoming data and handles messages accordingly
64
- def handle_data(data)
65
- @buffer << data
66
- while (message = Listen::TCP::Message.from_buffer(@buffer))
67
- handle_message(message)
68
- end
69
- rescue
70
- _log :error, format('TCP.handle_data crashed: %s:%s', $ERROR_INFO,
71
- $ERROR_POSITION * "\n")
72
- raise
73
- end
74
-
75
- # Handles incoming message by notifying of path changes
76
- def handle_message(message)
77
- type, change, dir, path, _ = message.object
78
- _log(:debug) { "TCP message: #{[type, change, dir, path].inspect}" }
79
-
80
- _queue_change(type.to_sym, Pathname(dir), path, change: change.to_sym)
81
- end
82
-
83
- def self.local_fs?
84
- false
85
- end
86
- end
87
- end
88
- end
@@ -1,35 +0,0 @@
1
- require 'celluloid/logger'
2
-
3
- module Listen
4
- module Internals
5
- module Logging
6
- def _info(*args, &block)
7
- _log(:info, *args, &block)
8
- end
9
-
10
- def _warn(*args, &block)
11
- _log(:warn, *args, &block)
12
- end
13
-
14
- def _debug(*args, &block)
15
- _log(:debug, *args, &block)
16
- end
17
-
18
- def _log(*args, &block)
19
- if block
20
- Celluloid::Logger.send(*args, block.call)
21
- else
22
- Celluloid::Logger.send(*args)
23
- end
24
- end
25
-
26
- def _format_error(fmt)
27
- format(fmt, $ERROR_INFO, ", Backtrace: \n" + $ERROR_POSITION * "\n")
28
- end
29
-
30
- def _error_exception(fmt)
31
- _log :error, _format_error(fmt)
32
- end
33
- end
34
- end
35
- end
data/lib/listen/tcp.rb DELETED
@@ -1,8 +0,0 @@
1
- begin
2
- require 'celluloid/io'
3
- rescue LoadError
4
- Kernel.fail 'TCP forwarding requires Celluloid::IO to be present. ' \
5
- "Please install or add as a dependency: gem 'celluloid-io'"
6
- end
7
-
8
- require 'listen/adapter/tcp'
@@ -1,79 +0,0 @@
1
- require 'celluloid/io'
2
-
3
- module Listen
4
- module TCP
5
- class Broadcaster
6
- include Celluloid::IO
7
-
8
- finalizer :finalize
9
-
10
- # Initializes a Celluloid::IO-powered TCP-broadcaster
11
- #
12
- # @param [String] host to broadcast on
13
- # @param [String] port to broadcast on
14
- #
15
- # Note: Listens on all addresses when host is nil
16
- #
17
- def initialize(host, port)
18
- @sockets = []
19
- _log :debug, format('Broadcaster: tcp server listening on: %s:%s',
20
- host, port)
21
- @server = TCPServer.new(host, port)
22
- rescue
23
- _log :error, format('Broadcaster.initialize: %s:%s', $ERROR_INFO,
24
- $ERROR_POSITION * "\n")
25
- raise
26
- end
27
-
28
- # Asynchronously start accepting connections
29
- def start
30
- async.run
31
- end
32
-
33
- # Cleans up sockets and server
34
- def finalize
35
- @sockets.map(&:close) if @sockets
36
- @sockets = nil
37
-
38
- return unless @server
39
- @server.close
40
- @server = nil
41
- end
42
-
43
- # Broadcasts given payload to all connected sockets
44
- def broadcast(payload)
45
- active_sockets = @sockets.select do |socket|
46
- _unicast(socket, payload)
47
- end
48
- @sockets.replace(active_sockets)
49
- end
50
-
51
- # Continuously accept and handle incoming connections
52
- def run
53
- while (socket = @server.accept)
54
- @sockets << socket
55
- end
56
- rescue Celluloid::Task::TerminatedError
57
- _log :debug, "TCP adapter was terminated: #{$ERROR_INFO}"
58
- rescue
59
- _log :error, format('Broadcaster.run: %s:%s', $ERROR_INFO,
60
- $ERROR_POSITION * "\n")
61
- raise
62
- end
63
-
64
- private
65
-
66
- def _log(type, message)
67
- Celluloid::Logger.send(type, message)
68
- end
69
-
70
- def _unicast(socket, payload)
71
- socket.write(payload)
72
- true
73
- rescue IOError, Errno::ECONNRESET, Errno::EPIPE
74
- _log :debug, "Broadcaster failed: #{socket.inspect}"
75
- false
76
- end
77
- end
78
- end
79
- end
@@ -1,50 +0,0 @@
1
- require 'json'
2
-
3
- module Listen
4
- module TCP
5
- class Message
6
- attr_reader :body, :object, :payload, :size
7
-
8
- HEADER_SIZE = 4
9
- HEADER_FORMAT = 'N'
10
- PAYLOAD_FORMAT = "#{HEADER_FORMAT}a*"
11
-
12
- # Initializes a new message
13
- #
14
- # @param [Object] object to initialize message with
15
- #
16
- def initialize(*args)
17
- self.object = args
18
- end
19
-
20
- # Generates message size and payload for given object
21
- def object=(obj)
22
- @object = obj
23
- @body = JSON.generate(@object)
24
- @size = @body.bytesize
25
- @payload = [@size, @body].pack(PAYLOAD_FORMAT)
26
- end
27
-
28
- # Extracts message size and loads object from given payload
29
- def payload=(payload)
30
- @payload = payload
31
- @size, @body = @payload.unpack(PAYLOAD_FORMAT)
32
- @object = JSON.parse(@body)
33
- end
34
-
35
- # Extracts a message from given buffer
36
- def self.from_buffer(buffer)
37
- if buffer.bytesize > HEADER_SIZE
38
- size = buffer.unpack(HEADER_FORMAT).first
39
- payload_size = HEADER_SIZE + size
40
- if buffer.bytesize >= payload_size
41
- payload = buffer.slice!(0...payload_size)
42
- new.tap do |message|
43
- message.payload = payload
44
- end
45
- end
46
- end
47
- end
48
- end
49
- end
50
- end