fan_out_on_write_service.rb 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. class FanOutOnWriteService < BaseService
  2. # Push a status into home and mentions feeds
  3. # @param [Status] status
  4. def call(status)
  5. deliver_to_self(status) if status.account.local?
  6. deliver_to_followers(status)
  7. deliver_to_mentioned(status)
  8. end
  9. private
  10. def deliver_to_self(status)
  11. push(:home, status.account.id, status)
  12. end
  13. def deliver_to_followers(status)
  14. status.account.followers.each do |follower|
  15. next if !follower.local? || FeedManager.filter_status?(status, follower)
  16. push(:home, follower.id, status)
  17. end
  18. end
  19. def deliver_to_mentioned(status)
  20. status.mentions.each do |mention|
  21. mentioned_account = mention.account
  22. next unless mentioned_account.local?
  23. push(:mentions, mentioned_account.id, status)
  24. end
  25. end
  26. def push(type, receiver_id, status)
  27. redis.zadd(FeedManager.key(type, receiver_id), status.id, status.id)
  28. trim(type, receiver_id)
  29. end
  30. def trim(type, receiver_id)
  31. return unless redis.zcard(FeedManager.key(type, receiver_id)) > FeedManager::MAX_ITEMS
  32. last = redis.zrevrange(FeedManager.key(type, receiver_id), FeedManager::MAX_ITEMS - 1, FeedManager::MAX_ITEMS - 1)
  33. redis.zremrangebyscore(FeedManager.key(type, receiver_id), '-inf', "(#{last.last}")
  34. end
  35. def redis
  36. $redis
  37. end
  38. end