最优雅的方式来跟踪“最后活跃”的时间

时间:2014-05-07 20:30:10

标签: ruby-on-rails ruby-on-rails-4

我有一个网站,我需要能够在每个用户的个人资料上显示他们上一次"活跃"在网站上。在这种情况下,"活跃"通过浏览内容,与其他用户互动以及完成课程来定义。

我的计划是在Users表上有一个last_active列,我可以使用Time.now更新。问题是,如果不在每个控制器操作期间访问数据库,我该如何做到这一点?这似乎......很贵。例如,我想避免这样做:

# In each controller
def index
  current_user.activity
end


# In the User model
def activity
  self.update_attribute(:last_active, Time.now)
end

因为每当用户获得内容列表时,我都必须进行数据库调用。

另一种选择是拥有一个Activity表,我用各种用户操作更新(类似于审计)。这将允许我存储和显示有关用户正在做什么的更多相关信息。但这又回到了同样的问题:如何在没有大量开销的情况下更新这些表?

4 个答案:

答案 0 :(得分:1)

这真是一个没有实际意义的问题 - 不,没有更新数据库就无法更新数据库。

如果你想变得复杂,你可以尝试做一些客户端脚本来将这些信息存储在会话变量或cookie中,并且偶尔将它提交给db,但这似乎很多一个小功能的工作。

也许如果您在:last_active列中添加索引,可能会让它稍微便宜一些?但除此之外,我会坚持下去,并试着对其更新的频率保守。

您还可以在更新之前检查Time.now > @user.last_active+10.minutes是否确保您不会经常写入数据库,但之后您只是查询而不是更好。 ..

答案 1 :(得分:1)

我不认为在您更新特定用户的最后一个活动状态时,可以绕过开销而不受限制。属性。

正如查理·伊根所提到的那样,你有两种选择:

  1. 只更新最后一个有效的'用户登录时的属性。通过这样做,您仍然可以在网站上获得用户的一般活动。

  2. 只更新最后一个有效的'特定活动的属性。例如,您在问题中提到用户可以完成课程。这似乎是一项相当重要的活动,所以请更新最后一次活动'属性。浏览内容等不太重要的活动可以忽略不计。

答案 2 :(得分:0)

请不要考虑redis | memcache | any_in_memory_storage这些数据?

答案 3 :(得分:0)

如果您对异步更新没问题,可以设置延迟的resque作业,删除以前的作业。

Resque.remove_delayed_selection RecordLastUserActivity, {
   |args| args[0]['user_id'] == current_user.id 
}
Resque.enqueue_at(10.minutes.from_now, RecordLastUserActivity, 
             user_id: current_user.id, last_seen_at: Time.now)

不确定这是否会提供更好的性能,但需要进行一些测试。