-
Notifications
You must be signed in to change notification settings - Fork 245
/
listener.rb
132 lines (98 loc) · 3.2 KB
/
listener.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
require 'English'
require 'listen/version'
require 'listen/backend'
require 'listen/silencer'
require 'listen/silencer/controller'
require 'listen/queue_optimizer'
require 'listen/fsm'
require 'listen/event/loop'
require 'listen/event/queue'
require 'listen/event/config'
require 'listen/listener/config'
module Listen
class Listener
include Listen::FSM
# Initializes the directories listener.
#
# @param [String] directory the directories to listen to
# @param [Hash] options the listen options (see Listen::Listener::Options)
#
# @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
#
def initialize(*dirs, &block)
options = dirs.last.is_a?(Hash) ? dirs.pop : {}
@config = Config.new(options)
eq_config = Event::Queue::Config.new(@config.relative?)
queue = Event::Queue.new(eq_config) { @processor.wakeup_on_event }
silencer = Silencer.new
rules = @config.silencer_rules
@silencer_controller = Silencer::Controller.new(silencer, rules)
@backend = Backend.new(dirs, queue, silencer, @config)
optimizer_config = QueueOptimizer::Config.new(@backend, silencer)
pconfig = Event::Config.new(
self,
queue,
QueueOptimizer.new(optimizer_config),
@backend.min_delay_between_events,
&block)
@processor = Event::Loop.new(pconfig)
super() # FSM
end
default_state :initializing
state :initializing, to: :backend_started
state :backend_started, to: [:frontend_ready, :stopped] do
backend.start
end
state :frontend_ready, to: [:processing_events, :stopped] do
processor.setup
end
state :processing_events, to: [:paused, :stopped] do
processor.resume
end
state :paused, to: [:processing_events, :stopped] do
processor.pause
end
state :stopped, to: [:backend_started] do
backend.stop # should be before processor.teardown to halt events ASAP
processor.teardown
end
# Starts processing events and starts adapters
# or resumes invoking callbacks if paused
def start
transition :backend_started if state == :initializing
transition :frontend_ready if state == :backend_started
transition :processing_events if state == :frontend_ready
transition :processing_events if state == :paused
end
# Stops both listening for events and processing them
def stop
transition :stopped
end
# Stops invoking callbacks (messages pile up)
def pause
transition :paused
end
# processing means callbacks are called
def processing?
state == :processing_events
end
def paused?
state == :paused
end
def ignore(regexps)
@silencer_controller.append_ignores(regexps)
end
def ignore!(regexps)
@silencer_controller.replace_with_bang_ignores(regexps)
end
def only(regexps)
@silencer_controller.replace_with_only(regexps)
end
private
attr_reader :processor
attr_reader :backend
end
end