[英]Rails, Heroku, and Resque: Long Running Background Job Optimization
[英]Rails 4 - Impressionist Inside of a Resque Background Job
我正在使用Rails 4 w /印象派和resque gem。
我正在使用印象派来记录我的文章显示页面上的唯一会话点击。 由于性能问题而且无需向用户显示匹配(仅限管理员),我希望将日志记录显示移至后台。
通常我会使用impressionist(@article, unique: [:session_hash])
记录一个印象impressionist(@article, unique: [:session_hash])
但是通过resque将它移到bg中我现在正在做这样的事情......
articles_controller:
def show
.
.
.
Resque.enqueue(ImpressionLogger, @article.id)
end
应用程序/工人/ impression_logger.rb:
class ImpressionLogger
@queue = :impression_queue
def self.perform(article_id)
article = Article.find(article_id)
impressionist(article, unique: [:session_hash])
end
end
当我这样设置时,当resque尝试处理作业时,它会返回undefined method "impressionist" for ImpressionLogger:Class
。 你认为最好的方法是什么? 我不确定如何在我的resque工作者中包含印象派方法。
印象派是否与捆绑器正确安装? 如果是这样,Rails应该将它加载到您的环境中。 我会检查你是否可以在你的Rails代码中的其他地方访问impressionist
功能(即不通过Resque)作为调试它的第一步。
问题
您的问题源于这样一个事实:由于在ActionController的任何实例上的引擎初始化程序中包含一个带有impressionist
方法的模块,因此Impressionist在控制器级别上工作:
https://github.com/charlotte-ruby/impressionist/blob/master/lib/impressionist/engine.rb#L11
您试图从Resque作业中调用的常规类调用impressionist方法,因此它不会定义该方法。
解
这有点粗,但是如果你真的想使用印象派,我们可以深入研究这个......看看这里找到的印象派方法的实际实现,我们看到以下内容:
def impressionist(obj,message=nil,opts={})
if should_count_impression?(opts)
if obj.respond_to?("impressionable?")
if unique_instance?(obj, opts[:unique])
obj.impressions.create(associative_create_statement({:message => message}))
end
else
# we could create an impression anyway. for classes, too. why not?
raise "#{obj.class.to_s} is not impressionable!"
end
end
end
假设你手动调用这样的东西(你想从resque工作中调用),关键是这三行:
if unique_instance?(obj, opts[:unique])
obj.impressions.create(associative_create_statement({:message => message}))
end
如果要实现此功能,if包装器似乎很重要。 它看起来像你做的。 对associative_create_statement
的调用似乎是根据控制器名称以及从Rack传递的参数(例如useragent字符串和ip地址( 此处 ))来提取参数。 因此,您必须在调用Resque作业之前解析这些值。
我在这一点上建议实现一个Resque类,它接受两个参数,一个article_id和你想要的印象参数。 然后,resque类将直接在可展示对象上创建印象。 您的Resque课程将成为:
class ImpressionLogger
@queue = :impression_queue
def self.perform(article_id, impression_params = {})
article = Article.find(article_id)
article.impressions.create(impression_params)
end
end
你的控制器方法看起来像这样:
def show
.
.
.
Resque.enqueue(ImpressionLogger, @article.id, associative_create_statement({message: nil})) if unique_instance?(@article, [:session_hash])
end
放弃
尽管这样做有一个相当大的免责声明......方法associative_create_statement
被标记为protected和unique_instance?
被标记为私有...所以这些都不是印象派宝石的公共API的一部分,所以这个代码可能会在gem的版本之间中断。
你是如何开始你的resque工人的? 如果您需要加载Rails环境,请尝试rake environment resque:work
。
https://github.com/resque/resque/wiki/FAQ#how-do-i-ensure-my-rails-classesenvironment-is-loaded
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.