activity_tracker.rb 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. # frozen_string_literal: true
  2. class ActivityTracker
  3. include Redisable
  4. EXPIRE_AFTER = 6.months.seconds
  5. def initialize(prefix, type)
  6. @prefix = prefix
  7. @type = type
  8. end
  9. def add(value = 1, at_time = Time.now.utc)
  10. key = key_at(at_time)
  11. case @type
  12. when :basic
  13. redis.incrby(key, value)
  14. when :unique
  15. redis.pfadd(key, value)
  16. end
  17. redis.expire(key, EXPIRE_AFTER)
  18. end
  19. def get(start_at, end_at = Time.now.utc)
  20. (start_at.to_date...end_at.to_date).map do |date|
  21. key = key_at(date.to_time(:utc))
  22. value = case @type
  23. when :basic
  24. redis.get(key).to_i
  25. when :unique
  26. redis.pfcount(key)
  27. end
  28. [date, value]
  29. end
  30. end
  31. def sum(start_at, end_at = Time.now.utc)
  32. keys = (start_at.to_date...end_at.to_date).flat_map { |date| [key_at(date.to_time(:utc)), legacy_key_at(date)] }.uniq
  33. case @type
  34. when :basic
  35. redis.mget(*keys).sum(&:to_i)
  36. when :unique
  37. redis.pfcount(*keys)
  38. end
  39. end
  40. class << self
  41. def increment(prefix)
  42. new(prefix, :basic).add
  43. end
  44. def record(prefix, value)
  45. new(prefix, :unique).add(value)
  46. end
  47. end
  48. private
  49. def key_at(at_time)
  50. "#{@prefix}:#{at_time.beginning_of_day.to_i}"
  51. end
  52. def legacy_key_at(at_time)
  53. "#{@prefix}:#{at_time.to_date.cweek}"
  54. end
  55. end