我正在使用collectiveidea/delayed_job來延遲我的Lesson模型中的makesandwich方法。它工作正常發展,但給人當生產運行下面的錯誤:如何在使用delayed_job時修復「NilClass#after錯誤」錯誤?
Worker(host:b75643e6-bc2b-4f9f-97ff-b31aa3c50b0f pid:2)] Starting job worker
[Worker(host:b75643e6-bc2b-4f9f-97ff-b31aa3c50b0f pid:2)] NilClass# completed after 0.0095
[Worker(host:b75643e6-bc2b-4f9f-97ff-b31aa3c50b0f pid:2)] 1 jobs processed at 5.5022 j/s, 0 failed ...
我怎樣才能解決這個問題?
這裏是我的模型和方法:
#encoding: utf-8
class Lesson < ActiveRecord::Base
attr_accessible :content, :title, :parsed_content, :html_content, :user_id
serialize :parsed_content, Array
serialize :html_content, Array
serialize :pinyin_content, Array
serialize :defined_content, Array
serialize :literal_content, Array
validates :title, :presence => true
validates :content, :presence => true
belongs_to :user
#before_update do |lesson|
# lesson.makesandwich
#end
after_create do |lesson|
lesson.makesandwich
end
def makesandwich
require 'rmmseg'
#require 'to_lang'
require 'bing_translator'
require 'ruby-pinyin'
self.parsed_content = []
RMMSeg::Dictionary.load_dictionaries
content = self.content
paragraphs = content.split(/\r\n\r\n/) #convert to array of paragraphs
self.parsed_content = paragraphs
paragraphs.each_with_index do |text, ti|
text = text.gsub("。", "^^.")
text = text.gsub("?", "~~?")
text = text.gsub("!", "||!")
text = text.gsub(":", ":") #fix missing colons
text = text.split(/[.?!]/u) #convert to an array
text.each do |s|
s.gsub!("^^", "。")
s.gsub!("~~", "?")
s.gsub!("||", "!")
#s.gsub!("———————————",":")
end
text.each_with_index do |val, index|
algor = RMMSeg::Algorithm.new(text[index])
splittext = []
loop do
tok = algor.next_token
break if tok.nil?
tex = tok.text.force_encoding('UTF-8')
splittext << tex
text[index] = splittext
end
paragraphs[ti] = text
end
end
bing = BingTranslator.new('8bacb905-c59b-4363-bbf5-89ef2c32c26e', 'g82QvinzO7GhmP7qJQpfxTMXzClSGX3yiPcsedFDXYQ=')
self.parsed_content = paragraphs
textarray = Marshal.load(Marshal.dump(paragraphs))
self.defined_content = Marshal.load(Marshal.dump(paragraphs))
self.literal_content = Marshal.load(Marshal.dump(paragraphs))
self.pinyin_content = Marshal.load(Marshal.dump(paragraphs))
textarray.each_with_index do |paragraph, pi|
paragraph.each_with_index do |sentence, si|
sentence.each_with_index do |word, wi|
if DictionaryEntry.find_by_simplified(word) != nil
self.defined_content[pi][si][wi] = DictionaryEntry.find_by_simplified(word).definition
#self.literal_content is down below
self.pinyin_content[pi][si][wi] = DictionaryEntry.find_by_simplified(word).pinyin
else
self.defined_content[pi][si][wi] = bing.translate(word, :from => 'zh-CHS', :to => 'en')
#self.defined_content[pi][si][wi] = word
#self.literal_content is down below
if PinYin.of_string(word, true).length > 1 #for punctuation
self.pinyin_content[pi][si][wi] = PinYin.of_string(word, true).join(" ").downcase
else
self.pinyin_content[pi][si][wi] = word
end
end
end
end
end
#Literal
literalarray = Marshal.load(Marshal.dump(paragraphs))
literalarray.each_with_index do |paragraph, pi|
paragraph.each_with_index do |sentence, si| #iterate array of sentence
literalarray[pi][si] = []
sentence.each_with_index do |word, wi| #iterate sentence's array of words
entrytobesliced = DictionaryEntry.find_by_simplified(word)
slicedentry = []
if entrytobesliced == nil
if word.length > 1 && word !~ /\w/ #/^\s*\w\d+\s*$/ #number regex #for cases where there is no DictionaryEntry
split = []
wordarray = word.split("").each_with_index() do |ws, wsi|
split << [DictionaryEntry.find_by_simplified(ws).definition]
end
literalarray[pi][si] << split
else
literalarray[pi][si] << [word] #in case none of the above work
end
else
entrytobesliced.simplified.each_char do |w|
singlechar = DictionaryEntry.find_by_simplified(w)
slicedentry << singlechar.definition.split("\", \"")
end
literalarray[pi][si] << slicedentry
end
self.literal_content = literalarray #slicedentry #literalarray
end
end
end
self.save
end
handle_asynchronously :makesandwich
end
這裏是工作在數據庫中是什麼樣子:
irb(main):012:0> job
=> #<Delayed::Backend::ActiveRecord::Job id: 5, priority: 0, attempts: 0, handler: "--- !ruby/object:Delayed::PerformableMethod\nattribu...", last_error: nil, run_at: "2013-01-13 19:42:38", locked_at: nil, failed_at: nil, locked_by: nil, queue: nil, created_at: "2013-01-13 19:42:38", updated_at: "2013-01-13 19:42:38">
這裏是處理:
irb(main):011:0> job.handler
=> "--- !ruby/object:Delayed::PerformableMethod\nattributes:\n id: 14\n title: test\n content: ! \"1最初,上帝創造了天地。\\r\\n\\r\\n2大地混沌蒼茫,深淵的表面一片黑暗。上帝發出的動力運行在水面上。\\r\\n\\r\\n3上帝說:「要有光。」光就出現了。4上帝看光是好的。上帝把光暗分開了。5上帝稱光爲「晝」,稱暗爲「夜」。過了晚上,到了早晨,是第一日。\\r\\n\\r\\n6上帝說:「水和水之間要有天空,把水上下分開。」7於是上帝造出天空把水分開,天空以下有水,天空以上也有水。事就這樣成了。8上帝稱天空爲「天」。過了晚上,到了早晨,是第二日。\\r\\n\\r\\n9上帝說:「天下的水要聚在一處,讓陸地露出來。」事就這樣成了。10上帝稱陸地爲「地」,稱聚起來的水爲「海」。上帝看這是好的。11上帝說:「地要長出青草和結種子的植物,又要長出結果子的樹木,各按其類;果子裏要有種子,在地上生長。」事就這樣成了。12地上長出青草和結種子的植物,各按其類;又長出結果子的樹木,果子裏都有種子,各按其類。上帝看這是好的。13過了晚上,到了早晨,是第三日。\\r\\n\\r\\n14上帝說:「天空要有光源,可以分晝夜,做記號,定季節、日子、年月。15光源要在天空普照大地。」事就這樣成了。16上帝造出兩大光源,大的管晝,小的管夜,又造星星。17上帝把光源放在天空,普照大地,18支配晝夜,分開光暗。上帝看這是好的。19過了晚上,到了早晨,是第四日。\\r\\n\\r\\n20上帝說:「水裏要涌現成羣的活物,地上要有飛禽在天空飛翔。」21於是上帝創造巨大的海獸,使水裏涌現各樣遊動的活物,各按其類;又創造各種有翅膀的飛禽,各按其類。上帝看這是好的。22上帝賜福給這些活物說:「要繁衍增多,充滿海洋;飛禽也要在地上增多。」23過了晚上,到了早晨,是第五日。\\r\\n\\r\\n24上帝說:「地要生出活物來,各按其類,就是牲畜、爬行的動物、地上的走獸,各按其類。」事就這樣成了。25上帝造出地上的走獸,各按其類;牲畜,各按其類;地上各樣爬行的動物,各按其類。上帝看這是好的。\\r\\n\\r\\n26上帝說:「我們要照我們的形像、按我們的樣式造人,讓他們管理海里的魚、天上的飛禽、地上的牲畜,以及全地和地上各樣爬行的動物。」27於是上帝照自己的形像創造人,就是照上帝的形像把人創造出來。上帝創造了男人和女人。28上帝賜福給他們,對他們說:「要繁衍增多,遍滿地面,開拓大地,也要管理海里的魚、天上的飛禽和地上各樣爬行的活物。」\\r\\n\\r\\n29上帝說:「全地上各樣結種子的植物和各樣結種子的果樹,我都賜給你們做食物。30至於地上各樣的走獸、天上各樣的飛禽、地上各樣有生命的爬行動物,我把一切青菜綠葉都賜給它們吃。」事就這樣成了。\\r\\n\\r\\n31上帝看他所造的一切,都非常好。過了晚上,到了早晨,是第六日。\"\n created_at: 2013-01-13 19:42:38.696201148 Z\n updated_at: 2013-01-13 19:42:38.696201148 Z\n parsed_content: []\n html_content: []\n literal_content: []\n pinyin_content: []\n defined_content: []\n user_id: 1\n"
我嘗試了你的建議,但它仍然無法工作。我不明白爲什麼它會在開發中起作用,但不在heroku上。 – webmagnets
本地數據庫可能在開發中更快,因爲它沒有任何負載。這裏有一些資源http://rails-bestpractices.com/posts/695-use-after_commit和http://alindeman.github.com/2011/10/02/after-save-and-background-jobs。 html –
謝謝,但將其更改爲after_commit沒有幫助。你有沒有其他想法可以探索? – webmagnets