Sha256: 45895c6c36fe668c760ecb21bd55d1bac65acf96ec922daedfa8646d7f71fbc0
Contents?: true
Size: 1.91 KB
Versions: 1
Compression:
Stored size: 1.91 KB
Contents
require 'pty' module Hatchet # spawns a process on Heroku, and keeps it open for writing # like `heroku run bash` class ProcessSpawn attr_reader :command, :app, :timeout, :pid TIMEOUT = 60 # seconds to bring up a heroku command like `heroku run bash` def initialize(command, app, timeout = nil) raise "need command" unless command.present? raise "need app" unless app.present? @command = "heroku run #{command} -a #{app.name}" @ready_regex = "^run.*up.*#{command}" @app = app @timeout = timeout || TIMEOUT end def ready? @ready ||= `heroku ps -a #{app.name}`.match(/#{@ready_regex}/).present? end def not_ready? !ready? end def wait_for_spawn! while not_ready? sleep 1 end return true end # some REPL's don't sync standard out by default # try to do it auto-magically def repl_magic(repl) case command when /rails\s*console/, /\sirb\s/ # puts "magic for: '#{command}'" repl.run("STDOUT.sync = true") end end # Open up PTY (pseudo terminal) to command like `heroku run bash` # Wait for the dyno to deploy, then allow user to run arbitrary commands def spawn_repl output, input, pid = PTY.spawn(command) stream = StreamExec.new(output, input, pid) repl = ReplRunner.new(stream) stream.timeout("waiting for spawn", timeout) do wait_for_spawn! end raise "Could not run: '#{command}', command took longer than #{timeout} seconds" unless self.ready? repl_magic(repl) repl.wait_for_boot(5) # important to get rid of startup info i.e. "booting rails console ..." return repl end def run(&block) return `#{command}` if block.blank? # one off command, no block given yield repl = spawn_repl ensure repl.close if repl.present? end end end
Version data entries
1 entries across 1 versions & 1 rubygems
Version | Path |
---|---|
heroku_hatchet-0.2.0 | lib/hatchet/process_spawn.rb |