Class: Stipa::Reloader

Inherits:
Object
  • Object
show all
Defined in:
lib/stipa/reloader.rb

Overview

Development file watcher that restarts the process when Ruby source files change.

Enabled when:

- STIPA_RELOAD=1 environment variable is set, OR
- reload: true is passed to App#start / Server#start

Strategy:

A background thread polls the mtime of all .rb files visible to Ruby
($LOADED_FEATURES) plus any extra watch paths supplied by the user.
When a change is detected it calls exec($0, *ARGV) which replaces the
current process image with a fresh one — same PID namespace, same
command line arguments, all changes picked up from scratch.

Why exec instead of in-process reload:

In-process reload requires clearing constants, unloading files, and
rebuilding the route table. exec is simpler, safer, and handles any
kind of change (routes, middleware, config, gems) without edge cases.

Constant Summary collapse

DEFAULT_INTERVAL =

seconds between polls

0.5

Instance Method Summary collapse

Constructor Details

#initialize(logger:, interval: DEFAULT_INTERVAL, watch: []) ⇒ Reloader

Returns a new instance of Reloader.



22
23
24
25
26
27
28
# File 'lib/stipa/reloader.rb', line 22

def initialize(logger:, interval: DEFAULT_INTERVAL, watch: [])
  @logger   = logger
  @interval = interval
  @extra    = Array(watch).map { |p| File.expand_path(p) }
  @mtimes   = {}
  @thread   = nil
end

Instance Method Details

#startObject



30
31
32
33
34
35
36
# File 'lib/stipa/reloader.rb', line 30

def start
  snapshot!
  @thread = Thread.new { watch_loop }
  @thread.name = 'stipa-reloader'
  @thread.abort_on_exception = false
  @logger.warn('reloader active — watching for file changes')
end

#stopObject



38
39
40
# File 'lib/stipa/reloader.rb', line 38

def stop
  @thread&.kill
end