File: listener.rb

package info (click to toggle)
ruby-listen 3.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 544 kB
  • sloc: ruby: 5,033; makefile: 9
file content (136 lines) | stat: -rw-r--r-- 3,246 bytes parent folder | download | duplicates (2)
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
133
134
135
136
# frozen_string_literal: true

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
    #
    # rubocop:disable Metrics/MethodLength
    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)

      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)

      initialize_fsm
    end
    # rubocop:enable Metrics/MethodLength

    start_state :initializing

    state :initializing, to: [:backend_started, :stopped]

    state :backend_started, to: [:processing_events, :stopped] do
      @backend.start
    end

    state :processing_events, to: [:paused, :stopped] do
      @processor.start
    end

    state :paused, to: [:processing_events, :stopped] do
      @processor.pause
    end

    state :stopped, to: [:backend_started] do
      @backend.stop # halt events ASAP
      @processor.stop
    end

    # Starts processing events and starts adapters
    # or resumes invoking callbacks if paused
    def start
      case state
      when :initializing
        transition :backend_started
        transition :processing_events
      when :paused
        transition :processing_events
      else
        raise ArgumentError, "cannot start from state #{state.inspect}"
      end
    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 stopped?
      state == :stopped
    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
  end
end