From 6deb9f966eb9a280cc16428ba9324ffc15ea60a8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 18 Aug 2016 15:49:51 +0200 Subject: Live timelines using ActionCable --- app/services/fan_out_on_write_service.rb | 35 +++++++++++++++++++++++--------- app/services/precompute_feed_service.rb | 2 +- 2 files changed, 26 insertions(+), 11 deletions(-) (limited to 'app/services') diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb index c8c775b93..34684a06f 100644 --- a/app/services/fan_out_on_write_service.rb +++ b/app/services/fan_out_on_write_service.rb @@ -10,13 +10,13 @@ class FanOutOnWriteService < BaseService private def deliver_to_self(status) - push(:home, status.account.id, status) + push(:home, status.account, status) end def deliver_to_followers(status) status.account.followers.each do |follower| next if !follower.local? || FeedManager.filter_status?(status, follower) - push(:home, follower.id, status) + push(:home, follower, status) end end @@ -24,23 +24,38 @@ class FanOutOnWriteService < BaseService status.mentions.each do |mention| mentioned_account = mention.account next unless mentioned_account.local? - push(:mentions, mentioned_account.id, status) + push(:mentions, mentioned_account, status) end end - def push(type, receiver_id, status) - redis.zadd(FeedManager.key(type, receiver_id), status.id, status.id) - trim(type, receiver_id) + def push(type, receiver, status) + redis.zadd(FeedManager.key(type, receiver.id), status.id, status.id) + trim(type, receiver) + ActionCable.server.broadcast("timeline:#{receiver.id}", message: inline_render(receiver, status)) end - def trim(type, receiver_id) - return unless redis.zcard(FeedManager.key(type, receiver_id)) > FeedManager::MAX_ITEMS + def trim(type, receiver) + return unless redis.zcard(FeedManager.key(type, receiver.id)) > FeedManager::MAX_ITEMS - last = redis.zrevrange(FeedManager.key(type, receiver_id), FeedManager::MAX_ITEMS - 1, FeedManager::MAX_ITEMS - 1) - redis.zremrangebyscore(FeedManager.key(type, receiver_id), '-inf', "(#{last.last}") + last = redis.zrevrange(FeedManager.key(type, receiver.id), FeedManager::MAX_ITEMS - 1, FeedManager::MAX_ITEMS - 1) + redis.zremrangebyscore(FeedManager.key(type, receiver.id), '-inf', "(#{last.last}") end def redis $redis end + + def inline_render(receiver, status) + rabl_scope = Class.new(BaseService) do + def initialize(account) + @account = account + end + + def current_user + @account.user + end + end + + Rabl::Renderer.new('api/statuses/show', status, view_path: 'app/views', format: :json, scope: rabl_scope.new(receiver)).render + end end diff --git a/app/services/precompute_feed_service.rb b/app/services/precompute_feed_service.rb index de4201a8f..c8050bbd0 100644 --- a/app/services/precompute_feed_service.rb +++ b/app/services/precompute_feed_service.rb @@ -8,7 +8,7 @@ class PrecomputeFeedService < BaseService Status.send("as_#{type}_timeline", account).order('created_at desc').limit(FeedManager::MAX_ITEMS).each do |status| next if type == :home && FeedManager.filter_status?(status, account) - redis.zadd(FeedManager.key(type, receiver_id), status.id, status.id) + redis.zadd(FeedManager.key(type, account.id), status.id, status.id) instant_return << status unless instant_return.size > limit end -- cgit