Mastodonを読む/タイムラインの表示その2(サーバ側)
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
[[Mastodonを読む]]
#contents
*はじめに [#a5eba948]
タイムライン取得処理、ここからはサーバ側の処理になります...
*app/controllers/app/v1/timelines_controller.rb [#l8bc8780]
前回確認したように、ホームのタイムラインを取得する際には...
#code(Ruby){{
def home
@statuses = Feed.new(:home, current_account).get(limi...
@statuses = cache_collection(@statuses)
set_maps(@statuses)
next_path = api_v1_home_timeline_url(pagination_param...
prev_path = api_v1_home_timeline_url(pagination_param...
set_pagination_headers(next_path, prev_path)
render :index
end
}}
*app/models/feed.rb [#x2036616]
Feedはmodelsの下にあります。(Feed自体は対応するデータベ...
そんなに長くないので全部貼り付け。
#code(Ruby){{
class Feed
def initialize(type, account)
@type = type
@account = account
end
def get(limit, max_id = nil, since_id = nil)
max_id = '+inf' if max_id.blank?
since_id = '-inf' if since_id.blank?
unhydrated = redis.zrevrangebyscore(key, "(#{max_id}"...
status_map = Status.where(id: unhydrated).cache_ids.m...
unhydrated.map { |id| status_map[id] }.compact
end
private
def key
FeedManager.instance.key(@type, @account.id)
end
def redis
Redis.current
end
end
}}
[[Redis>https://redis.io/]]はインメモリのデータストア、Fe...
で、保存してるIDリストに対応するStatusモデルを返すと。
**Feedのキャッシュ [#m3a67f78]
なんか引っかかります。そう、IDリストっていつの間にキャッ...
app/services/precompute_feed_service.rb
#code(Ruby){{
class PrecomputeFeedService < BaseService
# Fill up a user's home/mentions feed from DB and retur...
# @param [Symbol] type :home or :mentions
# @param [Account] account
def call(_, account)
redis.pipelined do
Status.as_home_timeline(account).limit(FeedManager:...
next if status.direct_visibility? || FeedManager....
redis.zadd(FeedManager.instance.key(:home, accoun...
end
end
end
private
def redis
Redis.current
end
end
}}
うむ、こいつがキャッシュしてるっぽい。
キャッシュしてるところが見つかったので、今度は、じゃあ誰...
app/workers/regeneration_worker.rb
#code(Ruby){{
class RegenerationWorker
include Sidekiq::Worker
sidekiq_options queue: 'pull', backtrace: true, unique:...
def perform(account_id, _ = :home)
PrecomputeFeedService.new.call(:home, Account.find(ac...
end
end
}}
でこいつは(ry、とさらにgrepしたところ、
app/controllers/application_controller.rb
#code(Ruby){{
class ApplicationController < ActionController::Base
before_action :set_user_activity
def set_user_activity
return unless !current_user.nil? && (current_user.cur...
# Mark user as signed-in today
current_user.update_tracked_fields(request)
# If the sign in is after a two week break, we need t...
RegenerationWorker.perform_async(current_user.account...
end
}}
これ以上は追いかけませんが、まあ動いているから動くのでし...
*app/views/app/v1/timelines/index.rabl [#z89735ab]
さて、余談気味な話が長くなりましたが、話をtimelines#home...
#code(Ruby){{
collection @statuses
extends('api/v1/statuses/show')
}}
RABLはhome#indexの時にも出てきたJSONを作るためのDSLです。...
*おわりに [#k857f785]
今回はサーバ側で行われるタイムライン取得処理を見てきまし...
終了行:
[[Mastodonを読む]]
#contents
*はじめに [#a5eba948]
タイムライン取得処理、ここからはサーバ側の処理になります...
*app/controllers/app/v1/timelines_controller.rb [#l8bc8780]
前回確認したように、ホームのタイムラインを取得する際には...
#code(Ruby){{
def home
@statuses = Feed.new(:home, current_account).get(limi...
@statuses = cache_collection(@statuses)
set_maps(@statuses)
next_path = api_v1_home_timeline_url(pagination_param...
prev_path = api_v1_home_timeline_url(pagination_param...
set_pagination_headers(next_path, prev_path)
render :index
end
}}
*app/models/feed.rb [#x2036616]
Feedはmodelsの下にあります。(Feed自体は対応するデータベ...
そんなに長くないので全部貼り付け。
#code(Ruby){{
class Feed
def initialize(type, account)
@type = type
@account = account
end
def get(limit, max_id = nil, since_id = nil)
max_id = '+inf' if max_id.blank?
since_id = '-inf' if since_id.blank?
unhydrated = redis.zrevrangebyscore(key, "(#{max_id}"...
status_map = Status.where(id: unhydrated).cache_ids.m...
unhydrated.map { |id| status_map[id] }.compact
end
private
def key
FeedManager.instance.key(@type, @account.id)
end
def redis
Redis.current
end
end
}}
[[Redis>https://redis.io/]]はインメモリのデータストア、Fe...
で、保存してるIDリストに対応するStatusモデルを返すと。
**Feedのキャッシュ [#m3a67f78]
なんか引っかかります。そう、IDリストっていつの間にキャッ...
app/services/precompute_feed_service.rb
#code(Ruby){{
class PrecomputeFeedService < BaseService
# Fill up a user's home/mentions feed from DB and retur...
# @param [Symbol] type :home or :mentions
# @param [Account] account
def call(_, account)
redis.pipelined do
Status.as_home_timeline(account).limit(FeedManager:...
next if status.direct_visibility? || FeedManager....
redis.zadd(FeedManager.instance.key(:home, accoun...
end
end
end
private
def redis
Redis.current
end
end
}}
うむ、こいつがキャッシュしてるっぽい。
キャッシュしてるところが見つかったので、今度は、じゃあ誰...
app/workers/regeneration_worker.rb
#code(Ruby){{
class RegenerationWorker
include Sidekiq::Worker
sidekiq_options queue: 'pull', backtrace: true, unique:...
def perform(account_id, _ = :home)
PrecomputeFeedService.new.call(:home, Account.find(ac...
end
end
}}
でこいつは(ry、とさらにgrepしたところ、
app/controllers/application_controller.rb
#code(Ruby){{
class ApplicationController < ActionController::Base
before_action :set_user_activity
def set_user_activity
return unless !current_user.nil? && (current_user.cur...
# Mark user as signed-in today
current_user.update_tracked_fields(request)
# If the sign in is after a two week break, we need t...
RegenerationWorker.perform_async(current_user.account...
end
}}
これ以上は追いかけませんが、まあ動いているから動くのでし...
*app/views/app/v1/timelines/index.rabl [#z89735ab]
さて、余談気味な話が長くなりましたが、話をtimelines#home...
#code(Ruby){{
collection @statuses
extends('api/v1/statuses/show')
}}
RABLはhome#indexの時にも出てきたJSONを作るためのDSLです。...
*おわりに [#k857f785]
今回はサーバ側で行われるタイムライン取得処理を見てきまし...
ページ名: