1

我有一个代表文档的模型,标题、作者等是从网络表格中抓取的,但是需要从 PDF 中提取内容,这需要时间和资源密集型。这似乎是使用delayed_jobs 的合乎逻辑的地方,但它总是失败,所以我想知道我是否缺少限制或GCE

#working code
doc = Document.new
doc.title = html_table.row[i].title
doc.author = html_table.row[i].author
doc.link = html_table.row[i].link
doc.load_pdf_text  # instance method which used the link extracted above to dowload a pdf and strip the text 
doc.save

上面的代码无需任何更改即可工作。我认为延迟作业允许用 send_later 调用替换直接方法调用并继续

#broken code
#same as above except
doc.send_later(:load_pdf_text)

此代码将始终失败作业,并且会抱怨访问作为模型一部分的私有方法,例如,下载 PDF 需要 URL。任何指针将不胜感激。

添加:

方法定义(链接和摘要是文档模型的数据库支持属性)

def load_pdf_text
  tmpfilename = "#{RAILS_ROOT}/tmp/tmp_"+Time.now.to_s.gsub(/ |-/,"_")
  Kernel.system("curl -s #{link} > #{tmpfilename}") # this is line 224
  a=""
  IO.popen("pdftotext -raw -l 1 #{tmpfilename} -"){ |pipe| a = pipe.read }
  Kernel.system("rm #{tmpfilename}")
  summary = a
  save
end

错误信息

--- !ruby/struct:Delayed::PerformableMethod 
object: AR:Memo:4089
method: :load_pdf_text
args: []

 | Attempt to call private method
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.2/lib/active_record/attribute_methods.rb:236:in `method_missing'
/Users/naven87/test/memos/app/models/memo.rb:224:in `load_pdf_text'
/Library/Ruby/Gems/1.8/gems/delayed_job-1.8.4/lib/delayed/performable_method.rb:23:in `send'
/Library/Ruby/Gems/1.8/gems/delayed_job-1.8.4/lib/delayed/performable_method.rb:23:in `perform'
/Library/Ruby/Gems/1.8/gems/delayed_job-1.8.4/lib/delayed/job.rb:215:in `invoke_job'
/Library/Ruby/Gems/1.8/gems/delayed_job-1.8.4/lib/delayed/job.rb:93:in `run_with_lock'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/timeout.rb:62:in `timeout'
/Library/Ruby/Gems/1.8/gems/delayed_job-1.8.4/lib/delayed/job.rb:93:in `run_with_lock'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/Library/Ruby/Gems/1.8/gems/delayed_job-1.8.4/lib/delayed/job.rb:92:in `run_with_lock'
/Library/Ruby/Gems/1.8/gems/delayed_job-1.8.4/lib/delayed/job.rb:153:in `reserve_and_run_one_job'
/Library/Ruby/Gems/1.8/gems/delayed_job-1.8.4/lib/delayed/job.rb:152:in `each'
/Library/Ruby/Gems/1.8/gems/delayed_job-1.8.4/lib/delayed/job.rb:152:in `reserve_and_run_one_job'
/Library/Ruby/Gems/1.8/gems/delayed_job-1.8.4/lib/delayed/job.rb:199:in `work_off'
/Library/Ruby/Gems/1.8/gems/delayed_job-1.8.4/lib/delayed/job.rb:198:in `times'
/Library/Ruby/Gems/1.8/gems/delayed_job-1.8.4/lib/delayed/job.rb:198:in `work_off'
/Library/Ruby/Gems/1.8/gems/delayed_job-1.8.4/lib/delayed/worker.rb:28:in `start'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/Library/Ruby/Gems/1.8/gems/delayed_job-1.8.4/lib/delayed/worker.rb:27:in `start'
/Library/Ruby/Gems/1.8/gems/delayed_job-1.8.4/lib/delayed/worker.rb:24:in `loop'
/Library/Ruby/Gems/1.8/gems/delayed_job-1.8.4/lib/delayed/worker.rb:24:in `start'
/Users/naven87/.gem/ruby/1.8/gems/collectiveidea-delayed_job-1.8.2/lib/delayed/tasks.rb:13
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:636:in `call'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:636:in `execute'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:in `each'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:in `execute'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:597:in `invoke_with_call_chain'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/monitor.rb:242:in `synchronize'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:590:in `invoke_with_call_chain'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:583:in `invoke'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:2051:in `invoke_task'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in `top_level'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in `each'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in `top_level'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:2023:in `top_level'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:2001:in `run'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:1998:in `run'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/bin/rake:31
/usr/bin/rake:19:in `load'
/usr/bin/rake:19 
4

2 回答 2

3

根据进一步调查,当延迟作业序列化对象并反序列化以实际发送消息时,它不再处于同一范围内,并且无法访问对象的任何私有实例方法。这很令人困惑,因为如果您没有通过延迟作业运行它,它会找到,但是一旦传递给延迟作业,它就不再充当对象在自身上运行方法,而是将方法发送到创建不同集合的对象权限。您需要公开实例方法或提供延迟作业可以用来执行任何其他私有操作的公共机制。

于 2011-04-13T05:35:18.567 回答
0

请在此处发布错误消息,如果可能,请发布模型源。同时,您可以通过将方法和参数doc作为显式消息发送到来解决此问题:

doc.send :send_later, :extract_pdf_text

但这不是解决方案。您应该重构代码,以免出现这些错误。

于 2009-12-09T11:01:21.673 回答