about summary refs log tree commit diff
path: root/app/services
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2016-09-10 18:36:48 +0200
committerEugen Rochko <eugen@zeonfederated.com>2016-09-10 18:36:48 +0200
commit0077fc26df2982720e5fb278af6540a47859386f (patch)
treec7de413748f9a235779cd354f06d291f84498183 /app/services
parent35b6c4b36aa483e9936315cb72c2cf1fd2f477f6 (diff)
Merge and unmerge timelines on follow/unfollow, solves #21, #22
Diffstat (limited to 'app/services')
-rw-r--r--app/services/base_service.rb1
-rw-r--r--app/services/fan_out_on_write_service.rb41
-rw-r--r--app/services/follow_service.rb15
-rw-r--r--app/services/precompute_feed_service.rb2
-rw-r--r--app/services/unfollow_service.rb15
5 files changed, 34 insertions, 40 deletions
diff --git a/app/services/base_service.rb b/app/services/base_service.rb
index 634653546..10c558109 100644
--- a/app/services/base_service.rb
+++ b/app/services/base_service.rb
@@ -3,6 +3,5 @@ class BaseService
   include ActionView::Helpers::SanitizeHelper
 
   include RoutingHelper
-  include ApplicationHelper
   include AtomBuilderHelper
 end
diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb
index 973451e33..b8e2f5c22 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, status)
+    FeedManager.instance.push(:home, status.account, status)
   end
 
   def deliver_to_followers(status)
     status.account.followers.each do |follower|
       next if !follower.local? || FeedManager.instance.filter_status?(status, follower)
-      push(:home, follower, status)
+      FeedManager.instance.push(:home, follower, status)
     end
   end
 
@@ -24,42 +24,7 @@ class FanOutOnWriteService < BaseService
     status.mentions.each do |mention|
       mentioned_account = mention.account
       next unless mentioned_account.local?
-      push(:mentions, mentioned_account, status)
+      FeedManager.instance.push(:mentions, mentioned_account, status)
     end
   end
-
-  def push(type, receiver, status)
-    redis.zadd(FeedManager.instance.key(type, receiver.id), status.id, status.id)
-    trim(type, receiver)
-    ActionCable.server.broadcast("timeline:#{receiver.id}", type: 'update', timeline: type, message: inline_render(receiver, status))
-  end
-
-  def trim(type, receiver)
-    return unless redis.zcard(FeedManager.instance.key(type, receiver.id)) > FeedManager::MAX_ITEMS
-
-    last = redis.zrevrange(FeedManager.instance.key(type, receiver.id), FeedManager::MAX_ITEMS - 1, FeedManager::MAX_ITEMS - 1)
-    redis.zremrangebyscore(FeedManager.instance.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
-
-      def current_account
-        @account
-      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/follow_service.rb b/app/services/follow_service.rb
index b775d3519..5ac758e69 100644
--- a/app/services/follow_service.rb
+++ b/app/services/follow_service.rb
@@ -15,12 +15,27 @@ class FollowService < BaseService
       NotificationWorker.perform_async(follow.stream_entry.id, target_account.id)
     end
 
+    merge_into_timeline(target_account, source_account)
     source_account.ping!(account_url(source_account, format: 'atom'), [Rails.configuration.x.hub_url])
     follow
   end
 
   private
 
+  def merge_into_timeline(from_account, into_account)
+    timeline_key = FeedManager.instance.key(:home, into_account.id)
+
+    from_account.statuses.find_each do |status|
+      redis.zadd(timeline_key, status.id, status.id)
+    end
+
+    FeedManager.instance.trim(:home, into_account.id)
+  end
+
+  def redis
+    $redis
+  end
+
   def follow_remote_account_service
     @follow_remote_account_service ||= FollowRemoteAccountService.new
   end
diff --git a/app/services/precompute_feed_service.rb b/app/services/precompute_feed_service.rb
index df2330d09..84d655437 100644
--- a/app/services/precompute_feed_service.rb
+++ b/app/services/precompute_feed_service.rb
@@ -6,7 +6,7 @@ class PrecomputeFeedService < BaseService
   def call(type, account, limit)
     instant_return = []
 
-    Status.send("as_#{type}_timeline", account).order('created_at desc').limit(FeedManager::MAX_ITEMS).each do |status|
+    Status.send("as_#{type}_timeline", account).order('created_at desc').limit(FeedManager::MAX_ITEMS).find_each do |status|
       next if type == :home && FeedManager.instance.filter_status?(status, account)
       redis.zadd(FeedManager.instance.key(type, account.id), status.id, status.id)
       instant_return << status unless instant_return.size > limit
diff --git a/app/services/unfollow_service.rb b/app/services/unfollow_service.rb
index 92d86a2c5..4d9c2a9a7 100644
--- a/app/services/unfollow_service.rb
+++ b/app/services/unfollow_service.rb
@@ -5,5 +5,20 @@ class UnfollowService < BaseService
   def call(source_account, target_account)
     follow = source_account.unfollow!(target_account)
     NotificationWorker.perform_async(follow.stream_entry.id, target_account.id) unless target_account.local?
+    unmerge_from_timeline(target_account, source_account)
+  end
+
+  private
+
+  def unmerge_from_timeline(from_account, into_account)
+    timeline_key = FeedManager.instance.key(:home, into_account.id)
+
+    from_account.statuses.find_each do |status|
+      redis.zrem(timeline_key, status.id)
+    end
+  end
+
+  def redis
+    $redis
   end
 end