Close
Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

PIVOTAL LABS
SF Standup 3/1/2010: JRuby skips ensure blocks when killed

When you kill a JRuby process (e.g. with a SIGINT) you can’t bank on ensure blocks being executed. Of course, this is worrisome – file handles and other connections won’t be closed. The problem boils down to this example:

$ cat kill_me.rb
begin
  sleep
ensure
  puts 'executed ensure'
end
$
$ ruby -v
ruby 1.8.6 (2008-08-11 patchlevel 287) [universal-darwin9.0]
$
$ ruby kill_me.rb
^Cexecuted ensure
kill_me.rb:2:in `sleep': Interrupt
    from kill_me.rb:2
$
$ jruby -v
jruby 1.4.0 (ruby 1.8.7 patchlevel 174) (2009-11-02 69fbfa3) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_13) [x86_64-java]
$
$ jruby kill_me.rb
^C$

Comments
  1. Mike Perham says:

    File handles and descriptors are associated with the process. The OS will clean them up when the process dies.

  2. Abhi Hiremagalur says:

    @Mike In the specific case that led us to this issue we were trying to ensure a connection to a JMS queue is closed gracefully; unfortunately this isn’t something the OS does when the JRuby process dies.

  3. Mike Perham says:

    When the process dies, the OS should close the socket and the JMS process on the other machine get notified of the socket closure. That’s the whole point of TCP (the infamous ‘remote server closed socket unexpectedly’ error). Now of course your JMS server might misbehave in this case…

  4. Jacob Maine says:

    For a more detailed discussion, check out the [JRuby dev mailing list](http://archive.codehaus.org/lists/org.codehaus.jruby.dev).

    @Mike Good point – things get cleaned up eventually, although not very gracefully. But there are a lot of scenarios where app code would want to tidy up after itself (delete files, etc.) that would be skipped if it were in the rescue/ensure blocks. In this case, we’re trying to be polite to the JMS server which, as you suggested, complains when we drop connections abruptly. Fortunately, there are work-arounds (register finalizers and/or write our own signal trapping).

    As we’ve researched, we’ve decided that it’s an expectations problem. As a Ruby programmer, I expect signals to raise Ruby exceptions, and trigger ensure blocks. But Java programmers have different expectations. So, it depends on whether you focus on the J(VM) part or Ruby part of JRuby.

Post a Comment

Your Information (Name required. Email address will not be displayed with comment.)

* Copy This Password *

* Type Or Paste Password Here *