Created
February 18, 2012 03:11
-
-
Save daveray/1857150 to your computer and use it in GitHub Desktop.
Working JRuby/Clojure dosync
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Hacked from headius' version here: https://github.com/headius/clojr/blob/master/src/main/java/com/headius/clojr/ClojrLibrary.java | |
// See also https://jira.codehaus.org/browse/JRUBY-6149 | |
public static IRubyObject dosync(final ThreadContext context, final IRubyObject self, final Block block) throws Exception { | |
final Ruby ruby = context.runtime; | |
return (IRubyObject) LockingTransaction.runInTransaction(new Callable() { | |
public Object call() throws Exception { | |
// re-get transaction in case this gets run in different threads | |
try { | |
final IRubyObject result = block.call(ruby.getCurrentContext()); | |
return result; | |
} catch (RaiseException e) { | |
final RubyException rubyException = e.getException(); | |
if(rubyException instanceof NativeException) { | |
// Peek in the native exception for RetryEx and retrow it raw. | |
// Otherwise retries won't work. The class name check is pretty | |
// kludgy, but RetryEx is package private :( | |
final NativeException ne = (NativeException) rubyException; | |
final Throwable cause = (Throwable) ne.getCause(); | |
if(cause != null && | |
"clojure.lang.LockingTransaction$RetryEx".equals(cause.getClass().getName())) { | |
throw (Error) cause; | |
} | |
else { | |
throw e; | |
} | |
} | |
else { | |
throw e; | |
} | |
} | |
} | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment