Question

I'm a DBA, and I stumbled upon such case: developers run irb sessions (from Ruby on Rails app). This irb keeps database connection open. Sometimes - they forget about it, and it keeps on "running" - not doign anything, but still using one db connection.

I'd like to add some kind of "idle timeout" to their irb config. Is it possible? How to do it?

Était-ce utile?

La solution

Here's a quick hack how you might implement this.

Note that this does not take into account that the user might be executing some long-running task inside the irb session. It simply looks at the time stamp of the last input; if it has not changed then it just flat out kills the process:

Update: it now checks if irb is currently running a command and ignores any timeouts if that is the case.

# Add some methods to IRB::Context and IRB::Irb
# for easier timeout implementation.
class IRB::Irb
  def status
    @signal_status
  end
end

class IRB::Context
  attr_reader :irb
  attr_reader :line_no

  def is_evaluating?
    self.irb.status == :IN_EVAL
  end
end

# Implement an auto exit timer thread. Timeout is given in seconds.
module IRB
  def self.auto_exit_after(timeout = 60)
    Thread.new {
      context    = IRB.conf[:MAIN_CONTEXT]
      last_input = Time.now
      last_line  = context.line_no

      loop {
        sleep 10

        # Check if irb is running a command
        if context.is_evaluating?
          # Reset the input time and ignore any timeouts
          last_input = Time.now
          next
        end

        # Check for new input
        if last_line != context.line_no
          # Got new input
          last_line  = context.line_no
          last_input = Time.now
          next
        end

        # No new input, check if idle time exceeded
        if Time.now - last_input > timeout    
          $stderr.puts "\n** IRB exiting due to idle timeout. Goodbye..."
          Process.kill("KILL", Process.pid)
        end
      }
    }
  end
end

To use it add the code to .irbrc, or some other place that auto-loads when irb is started, and then just start the timer:

IRB.auto_exit_after(60)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top