如何在线程中使用Ruby Java Bridge(Sidekiq)

时间:2014-10-30 10:03:37

标签: ruby-on-rails multithreading sidekiq rjb

我写了一个小的Java类来读取xls文件中的嵌入式图像,并且需要在我的Ruby on Rails应用程序的后台进程(使用Sidekiq)中使用它。但看起来线程存在一些问题,因为当sidekiq进程开始执行使用Rjb的方法时,JVM会抛出错误guarantee(get_thread() == thread) failed: must be the same thread, quickly

这是我设置它的方式。

我写了一个初始化器来设置rjb

require 'rjb'

JARS = Dir.glob("#{Rails.root}/lib/java_libs/*.jar").join(':')
Rjb::load(JARS)
EXCEL_IMAGE_READER = Rjb::import('tools.ImageReader')

然后我在后台进程中使用它

  def get_excel_images
    p 'Starting to get the images'
    images = []
    image_reader = EXCEL_IMAGE_READER.new(@excel_path)
    image_reader.get_file_names.each do |file_name|
      images << Attachment.new_from_bytes(image_reader.get_file(file_name), file_name)
    end
    images
  end

但是一旦该方法开始执行,JVM就会抛出异常。这是Sidekiq的日志。

2014-10-30T09:47:02Z 11748 TID-17e7qk INFO: Running in ruby 2.1.1p76 (2014-02-24 revision 45161) [i686-linux]
2014-10-30T09:47:02Z 11748 TID-17e7qk INFO: See LICENSE and the LGPL-3.0 for licensing details.
2014-10-30T09:47:02Z 11748 TID-17e7qk INFO: Starting processing, hit Ctrl-C to stop
2014-10-30T09:47:31Z 11748 TID-19393k Sidekiq::Extensions::DelayedClass JID-08eac9ed686f8d6146cda67f INFO: start
"Starting to get the images"
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (threadLocalStorage.cpp:60), pid=11748, tid=2960567104
#  guarantee(get_thread() == thread) failed: must be the same thread, quickly
#
# JRE version: OpenJDK Runtime Environment (7.0_65-b32) (build 1.7.0_65-b32)
# Java VM: OpenJDK Client VM (24.65-b04 mixed mode, sharing linux-x86 )
# Derivative: IcedTea 2.5.3
# Distribution: Ubuntu 12.04 LTS, package 7u71-2.5.3-0ubuntu0.12.04.1
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/mika/projects/my_project/hs_err_pid11748.log
#
# If you would like to submit a bug report, please include
# instructions on how to reproduce the bug and visit:
#   http://icedtea.classpath.org/bugzilla
#
Aborted (core dumped)

我尝试将初始化程序中的内容移动到get_excel_images方法,但它没有任何效果。如果我直接从控制台或通过rspec测试运行它,代码就可以工作。

有没有人有任何想法如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

我从Rjb Github问题https://github.com/arton/rjb/issues/24找到了一些信息。看起来降级为ruby 1.9.3和rjb 1.4.9可能会解决这个问题,但这不是一个好的解决方案,因为ruby 1.9.3只会在几个月内收到安全补丁。问题在于如何创建线程以及它如何从ruby 1.9.3更改为ruby 2.

在尝试了许多不同的解决方案后,我搬到了JRuby。现在java交互很容易。

更新:

在JRuby缓慢度过了一年后,我将所有Java内容移动到一个独立的守护进程中,并通过TCP Socket使用JSON与守护进程通信来传输数据。现在我回到了MRI Ruby中,开发再次感到愉快。