Last active
October 3, 2018 08:33
-
-
Save matsadler/8b4cc374276143593e80 to your computer and use it in GitHub Desktop.
Simple Ruby app preloader.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require "socket" | |
# This is a simple preloader for Ruby apps. | |
# Usage: | |
# Put this file somewhere in your PATH, named 'ruby_preloader' and make sure | |
# it's executable. | |
# Add whatever you need to load your app environment to a .preload.rb in the | |
# base directory of your project. | |
# Add #!/usr/bin/env ruby_preload as the first line of any script you want to | |
# run with a preloaded environment. | |
# Run, and keep running, 'ruby_preload' from the base directory of your project. | |
# Run your script, it should now load quickly. | |
script = ARGV.last | |
exec("ruby", "--version") if script == "--version" | |
script, reload = nil, true if script == "--reload" | |
Dir.mkdir("/tmp/ruby_preload") unless File.exist?("/tmp/ruby_preload") | |
sock_path = "/tmp/ruby_preload/#{Dir.pwd.tr("^a-zA-Z0-9", "_")}_sock" | |
std_io = [STDIN, STDOUT, STDERR] | |
if script | |
abort("ruby_preload server not running") unless File.exist?(sock_path) | |
sock = UNIXSocket.new(sock_path) | |
sock.puts(script) | |
pid = sock.gets.to_i | |
(Signal.list.keys - %W{ILL FPE BUS SEGV VTALRM KILL STOP}).each do |name| | |
Signal.trap(name) {Process.kill(name, pid)} | |
end | |
std_io.each {|io| sock.send_io(io)} | |
exit(sock.gets.to_i) | |
else | |
server = UNIXServer.new(sock_path) | |
begin | |
require "#{Dir.pwd}/.preload" if File.exist?(".preload.rb") | |
rescue Exception => e | |
File.unlink(sock_path) | |
raise | |
end | |
is_parent = true | |
while is_parent | |
begin | |
sock = server.accept | |
script = sock.gets.chomp | |
is_parent = fork | |
File.unlink(sock_path) && exec($0, "--reload") if is_parent && reload | |
rescue Exception => e | |
File.unlink(sock_path) | |
Interrupt === e ? exit : raise | |
end | |
end | |
server.close | |
sock.puts(Process.pid) | |
std_io.each {|io| io.reopen(sock.recv_io)} | |
begin | |
load script | |
ensure | |
sock.puts($! ? $!.respond_to?(:status) ? $!.status : 1 : 0) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment