Skip to content

Instantly share code, notes, and snippets.

@arielvalentin
Forked from jorgenpt/jruby_timeout.rb
Last active December 23, 2015 09:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save arielvalentin/6614461 to your computer and use it in GitHub Desktop.
Save arielvalentin/6614461 to your computer and use it in GitHub Desktop.
Don't use this
# Workaround for IO.popen.readlines being allowed to block indefinitely even if
# wrapped in a Timeout::timeout call.
#
# Test case:
# $ time jruby -rtimeout -e "timeout(1) { IO.popen('sleep 10').readlines }"
# * Propagating errors executed in the block
# * Thread.raise experiences a TypeError because it cannot convert a java Exception into a ruby Error so I've added handling any errors raised from the java code to be propagated correctly
# * Renamed some variables so that they matched
require 'timeout'
#
# Note: if the yield'd code can throw a Java exception, you *must* catch it in your timeout block
# Code inspired by https://gist.github.com/jorgenpt/1356797
# Due to JRUBY Bug http://jira.codehaus.org/browse/JRUBY-6974
#
module Timeout
def self.timeout(sec, klass=nil)
return yield(sec) if sec == nil or sec.zero?
x = Thread.current
thread = Thread.new {
begin
yield(sec)
rescue Java::JavaLang::Throwable => t
x.raise RuntimeError.new("%s\n%s" % [t.inspect, t.backtrace.join("\n")])
rescue => e
x.raise e
end
}
if thread.join(sec).nil?
java_thread = JRuby.reference(thread)
thread.kill
java_thread.native_thread.interrupt
thread.join(0.15)
raise (klass || Error), 'execution expired'
else
thread.value
end
end
end
include Timeout
Found one Java-level deadlock:
=============================
"http-/192.168.220.196:8080-8192":
waiting to lock monitor 0x00007fca797bffa8 (object 0x00000005a6894000, a org.jruby.internal.runtime.ThreadService),
which is held by "http-/192.168.220.196:8080-598"
"http-/192.168.220.196:8080-598":
waiting to lock monitor 0x00007fca390d0600 (object 0x00000006dd8466c0, a org.jruby.RubyThread),
which is held by "RubyThread-3685559: /opt/datarouter/app/data_router.rb:106"
"RubyThread-3685559: /opt/datarouter/app/data_router.rb:106":
waiting to lock monitor 0x00007fca797bffa8 (object 0x00000005a6894000, a org.jruby.internal.runtime.ThreadService),
which is held by "http-/192.168.220.196:8080-598"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment