我正在尝试在Rails应用程序中编写一个小功能,该应用程序使用random-word gem生成随机名词,然后将其复数。我第一次访问开发中的页面时能够让它工作,但是我想让脚本在每次加载页面时再次运行。现在,后续页面加载(直到我退回服务器)给我FiberError in WelcomeController#randomwords
,fiber called across threads
。我试图自己解决这个问题,但我对编程很陌生,并不太了解Fibers的工作原理。我尝试使用Queue,但无法弄清楚如何让它工作,再次因为我不完全理解这个类。我该如何解决这个具体问题?
资料来源:welcome_helper.rb
def random
noun = RandomWord.nouns.next.split('_').sample.pluralize
if noun.include? "_"
noun = noun.split("_").join.pluralize
else
noun.pluralize!
end
return noun
end
答案 0 :(得分:1)
正如您现在可能已经发现的那样,问题是random-word
gem不是线程安全的。更准确地说,RandomWord.nouns
是module-level Enumerator和accessing enumerators across threads is not safe
但是,例如Queue
是线程安全的,因此对于此功能的线程安全替代方法,您可以使用nouns.dat
from the random-word gem,并在初始化应用程序时随机将其所有单词随机混合到Queue
对象中。现在,假设可以通过random_words_queue
方法范围内的random
访问此队列。然后,您可以将random
方法实现为
def random
unless random_words_queue.empty?
noun = random_words_queue.pop
if noun.include? "_"
noun = noun.split("_").join.pluralize
else
noun.pluralize!
end
return noun
end
end
请注意,如果队列为空,它当前只返回nil
,这可能是您不想要的。在这种情况下,您希望它的行为取决于您的要求:
noun
推到队列的后面。(无论如何,返回nil
可能不是任何人想要的。)