listen 2.10.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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