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?

Was it helpful?

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)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top