You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
1.4 KiB

  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 = begin
  23. case @type
  24. when :basic
  25. redis.get(key).to_i
  26. when :unique
  27. redis.pfcount(key)
  28. end
  29. end
  30. [date, value]
  31. end
  32. end
  33. def sum(start_at, end_at = Time.now.utc)
  34. keys = (start_at.to_date...end_at.to_date).flat_map { |date| [key_at(date.to_time(:utc)), legacy_key_at(date)] }.uniq
  35. case @type
  36. when :basic
  37. redis.mget(*keys).map(&:to_i).sum
  38. when :unique
  39. redis.pfcount(*keys)
  40. end
  41. end
  42. class << self
  43. def increment(prefix)
  44. new(prefix, :basic).add
  45. end
  46. def record(prefix, value)
  47. new(prefix, :unique).add(value)
  48. end
  49. end
  50. private
  51. def key_at(at_time)
  52. "#{@prefix}:#{at_time.beginning_of_day.to_i}"
  53. end
  54. def legacy_key_at(at_time)
  55. "#{@prefix}:#{at_time.to_date.cweek}"
  56. end
  57. end