Ale*_*son 7 ruby ruby-on-rails fiber
我正在尝试在Rails应用程序中编写一个小功能,该应用程序使用随机词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
Run Code Online (Sandbox Code Playgroud)
正如您现在可能已经发现的那样,问题在于 gemrandom-word不是线程安全的。更准确地说,RandomWord.nouns是一个模块级的 Enumerator,跨线程访问枚举器是不安全的
但是,egQueue是线程安全的,因此对于此功能的线程安全替代方案,您可以nouns.dat从随机单词 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
Run Code Online (Sandbox Code Playgroud)
请注意,当前它仅在nil队列为空时返回,而您可能不希望出现这种情况。在这种情况下,您希望它如何表现取决于您的要求:
noun在弹出它后立即将其推到队列后面。(无论如何,返回nil可能不是任何人想要的。)