Class: UnicornDirectoryWatcher::Runner

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app_name, root_dir, params = {}) ⇒ Runner

Returns a new instance of Runner.



12
13
14
15
16
17
18
19
20
# File 'lib/unicorn_directory_watcher.rb', line 12

def initialize(app_name, root_dir, params={})
  @app_name, @root_dir = app_name, root_dir
  @watcher_globs = params[:watcher_globs] || {
    root_dir => "{app,lib,vendor}/**/*.rb"
  }
  @pid_file = (params[:pid_file] || "#{root_dir}/tmp/pids/unicorn.pid").tap do |pid_file|
    FileUtils.mkdir_p File.dirname(File.expand_path(pid_file))
  end
end

Instance Attribute Details

#app_nameObject (readonly)

Returns the value of attribute app_name.



10
11
12
# File 'lib/unicorn_directory_watcher.rb', line 10

def app_name
  @app_name
end

#pid_fileObject (readonly)

Returns the value of attribute pid_file.



10
11
12
# File 'lib/unicorn_directory_watcher.rb', line 10

def pid_file
  @pid_file
end

#root_dirObject (readonly)

Returns the value of attribute root_dir.



10
11
12
# File 'lib/unicorn_directory_watcher.rb', line 10

def root_dir
  @root_dir
end

#watcher_globsObject (readonly)

Returns the value of attribute watcher_globs.



10
11
12
# File 'lib/unicorn_directory_watcher.rb', line 10

def watcher_globs
  @watcher_globs
end

Instance Method Details

#call {|_self| ... } ⇒ Object

Yields:

  • (_self)

Yield Parameters:



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
# File 'lib/unicorn_directory_watcher.rb', line 22

def call(&block)
  if RUBY_PLATFORM =~ /darwin/
    EM.kqueue = true
  else
    EM.epoll = true
  end

  # start the unicorn
  yield(self)

  master_pid = lambda do
    File.exists?(pid_file) ? File.read(pid_file).strip.to_i : nil
  end

  directory_watchers = watcher_globs.map do |dir, glob|
    # watch our app for changes
    dw = DirectoryWatcher.new dir,
      :glob => glob,
      :scanner => :em,
      :pre_load => true

      # SIGHUP makes unicorn respawn workers
    dw.add_observer do |*args|
      old_pid = master_pid.call
      Process.kill :USR2, old_pid
      start = Time.now
      loop do
        raise TimeoutError if Time.now - start > 5
        break if master_pid.call != old_pid
        sleep 0.5
      end
      Process.kill :QUIT, old_pid
    end

    dw
  end

    # wrap this in a lambda, just to avoid repeating it
  stop = lambda { |sig|
    master_pid.call.tap do |pid|
      begin
        Process.kill :QUIT, pid if pid
      rescue Errno::ESRCH
      end
    end
    directory_watchers.each do |dw|
      dw.stop
    end
    exit
  }

  trap("INT", stop)

  directory_watchers.each do |dw|
    dw.start
  end
  sleep
end