add: cache service

This commit is contained in:
yystopf 2021-10-25 16:57:11 +08:00
parent 401798ebdd
commit f9bb74aba4
9 changed files with 844 additions and 0 deletions

View File

@ -0,0 +1,26 @@
module AvatarHelper
def relative_path
"avatars"
end
def storage_path
File.join(Rails.root, "public", "images", relative_path)
end
def disk_filename(source_type,source_id,image_file=nil)
File.join(storage_path, "#{source_type}", "#{source_id}")
end
def url_to_avatar(source)
if File.exist?(disk_filename(source&.class, source&.id))
ctime = File.ctime(disk_filename(source.class, source.id)).to_i
if %w(User Organization).include?(source.class.to_s)
File.join("images", relative_path, ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}"
else
File.join("images/avatars", ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}"
end
elsif source.class.to_s == 'User'
source.get_letter_avatar_url
end
end
end

View File

@ -0,0 +1,16 @@
class CacheAsyncResetJob < ApplicationJob
queue_as :cache
def perform(type, id, params={})
case type
when "owner_common_service"
Cache::V2::OwnerCommonService.new(id).reset
when "platform_statistic_service"
Cache::V2::PlatformStatisticService.new.reset
when "project_common_service"
Cache::V2::ProjectCommonService.new(id).reset
when "user_statistic_service"
Cache::V2::PlatformStatisticService.new(id).reset
end
end
end

View File

@ -0,0 +1,16 @@
class CacheAsyncResetJob < ApplicationJob
queue_as :cache
def perform(type, id, params={})
case type
when "owner_common_service"
Cache::V2::OwnerCommonService.new(id, params).call
when "platform_statistic_service"
Cache::V2::PlatformStatisticService.new(params).call
when "project_common_service"
Cache::V2::ProjectCommonService.new(id, params).call
when "user_statistic_service"
Cache::V2::PlatformStatisticService.new(id, params).call
end
end
end

View File

@ -0,0 +1,89 @@
class Cache::V2::OwnerCommonService < ApplicationService
include AvatarHelper
attr_reader :owner_id, :login, :name, :avatar_url, :email
attr_accessor :owner
def initialize(owner_id, params={})
@owner_id = owner_id
@name = params[:name]
@email = params[:email]
end
def read
owner_common
end
def call
load_owner
set_owner_common
end
def reset
reset_owner_common
end
private
def load_owner
@owner = User.find_by_id(@owner_id)
end
def owner_common_key
"v2-owner-common:#{@owner_id}"
end
def owner_common
$redis_cache.hgetall(owner_common_key).blank? ? reset_owner_common : $redis_cache.hgetall(owner_common_key)
end
def set_owner_common
if $redis_cache.hgetall(owner_common_key).blank?
reset_owner_common
return
end
if @name.present?
if $redis_cache.hget(owner_common_key, "name").nil?
reset_owner_name
else
$redis_cache.hset(owner_common_key, "name", @name)
$redis_cache.hset(owner_common_key, "avatar_url", url_to_avatar(owner))
end
end
if @email.present?
if $redis_cache.hget(owner_common_key, "email").nil?
reset_owner_email
else
$redis_cache.hset(owner_common_key, "email", @email)
end
end
$redis_cache.hgetall(owner_common_key)
end
def reset_owner_type
$redis_cache.hset(owner_common_key, "type", owner&.type)
end
def reset_owner_login
$redis_cache.hset(owner_common_key, "login", owner&.login)
end
def reset_owner_email
$redis_cache.hset(owner_common_key, "email", owner&.mail)
end
def reset_owner_name
$redis_cache.hset(owner_common_key, "name", owner&.real_name)
$redis_cache.hset(owner_common_key, "avatar_url", url_to_avatar(owner))
end
def reset_owner_common
load_owner
$redis_cache.del(owner_common_key)
reset_owner_type
reset_owner_login
reset_owner_email
reset_owner_name
$redis_cache.hgetall(owner_common_key)
end
end

View File

@ -0,0 +1,182 @@
class Cache::V2::PlatformStatisticService < ApplicationService
attr_reader :follow_count, :fork_count, :issue_count, :project_count, :project_language_count_key, :project_language_count, :project_praise_count, :project_watcher_count, :pullrequest_count
def initialize(params={})
@follow_count = params[:follow_count]
@fork_count = params[:fork_count]
@issue_count = params[:issue_count]
@project_count = params[:project_count]
@project_language_count_key = params[:project_language_count_key]
@project_language_count = params[:project_language_count]
@project_praise_count = params[:project_praise_count]
@project_watcher_count = params[:project_watcher_count]
@pullrequest_count = params[:pullrequest_count]
end
def read
platform_statistic
end
def call
set_platform_statistic
end
def reset
reset_platform_statistic
end
private
def platform_statistic_key
"v2-platform-statistic"
end
def follow_count_key
"follow-count"
end
def fork_count_key
"fork-count"
end
def issue_count_key
"issue-count"
end
def project_count_key
"project-count"
end
def project_language_key
"project-language"
end
def project_praise_count_key
"project-praise-count"
end
def project_watcher_count_key
"project-watcher-count"
end
def pullrequest_count_key
"pullrequest-count"
end
def platform_statistic
$redis_cache.hgetall(platform_statistic_key).blank? ? reset_platform_statistic : $redis_cache.hgetall(platform_statistic_key)
end
def set_platform_statistic
if $redis_cache.hgetall(platform_statistic_key).blank?
reset_platform_statistic
return
end
if @follow_count.present?
if $redis_cache.hget(platform_statistic_key, follow_count_key).nil?
reset_platform_follow_count
else
$redis_cache.hincrby(platform_statistic_key, follow_count_key, @follow_count)
end
end
if @fork_count.present?
if $redis_cache.hget(platform_statistic_key, fork_count_key).nil?
reset_platform_fork_count
else
$redis_cache.hincrby(platform_statistic_key, fork_count_key, @fork_count)
end
end
if @issue_count.present?
if $redis_cache.hget(platform_statistic_key, issue_count_key).nil?
reset_platform_issue_count
else
$redis_cache.hincrby(platform_statistic_key, issue_count_key, @issue_count)
end
end
if @project_count.present?
if $redis_cache.hget(platform_statistic_key, project_count_key).nil?
reset_platform_project_count
else
$redis_cache.hincrby(platform_statistic_key, project_count_key, @project_count)
end
end
if @project_language_count_key.present? && project_language_count.present?
if $redis_cache.hget(platform_statistic_key, project_language_key).nil?
reset_platform_project_language
else
result = JSON.parse($redis_cache.hget(platform_statistic_key, project_language_key))
result[@project_language_count_key] ||= 0
result[@project_language_count_key] += project_language_count.to_i
$redis_cache.hset(platform_statistic_key, project_language_key, result.to_json)
end
end
if @project_praise_count.present?
if $redis_cache.hget(platform_statistic_key, project_praise_count_key).nil?
reset_platform_project_praise_count
else
$redis_cache.hincrby(platform_statistic_key, project_praise_count_key, @project_praise_count)
end
end
if @project_watcher_count.present?
if $redis_cache.hget(platform_statistic_key, project_watcher_count_key).nil?
reset_platform_project_watcher_count
else
$redis_cache.hincrby(platform_statistic_key, project_watcher_count_key, @project_watcher_count)
end
end
if @pullrequest_count.present?
if $redis_cache.hget(platform_statistic_key, pullrequest_count_key).nil?
reset_platform_pullrequest_count
else
$redis_cache.hincrby(platform_statistic_key, pullrequest_count_key, @pullrequest_count)
end
end
$redis_cache.hgetall(platform_statistic_key)
end
def reset_platform_follow_count
$redis_cache.hset(platform_statistic_key, follow_count_key, Watcher.where(watchable_type: 'User').count)
end
def reset_platform_fork_count
$redis_cache.hset(platform_statistic_key, fork_count_key, ForkUser.count)
end
def reset_platform_issue_count
$redis_cache.hset(platform_statistic_key, issue_count_key, Issue.count)
end
def reset_platform_project_count
$redis_cache.hset(platform_statistic_key, project_count_key, Project.count)
end
def reset_platform_project_language
$redis_cache.hset(platform_statistic_key, project_language_key, ProjectLanguage.where.not(projects_count: 0).group("project_languages.name").sum(:projects_count).to_json)
end
def reset_platform_project_praise_count
$redis_cache.hset(platform_statistic_key, project_praise_count_key, PraiseTread.where(praise_tread_object_type: "Project").count)
end
def reset_platform_project_watcher_count
$redis_cache.hset(platform_statistic_key, project_watcher_count_key, Watcher.where(watchable_type: 'Project').count)
end
def reset_platform_pullrequest_count
$redis_cache.hset(platform_statistic_key, pullrequest_count_key, PullRequest.count)
end
def reset_platform_statistic
$redis_cache.del(platform_statistic_key)
reset_platform_follow_count
reset_platform_fork_count
reset_platform_issue_count
reset_platform_project_count
reset_platform_project_language
reset_platform_project_praise_count
reset_platform_project_watcher_count
reset_platform_pullrequest_count
$redis_cache.hgetall(platform_statistic_key)
end
end

View File

@ -0,0 +1,211 @@
class Cache::V2::ProjectCommonService < ApplicationService
attr_reader :project_id, :owner_id, :name, :identifier, :visits, :watchers, :praises, :forks, :issues, :pullrequests
attr_accessor :project
def initialize(project_id, params={})
@project_id = project_id
@owner_id = params[:owner_id]
@name = params[:name]
@identifier = params[:identifier]
@visits = params[:visits]
@watchers = params[:watchers]
@praises = params[:praises]
@forks = params[:forks]
@issues = params[:issues]
@pullrequests = params[:pullrequests]
end
def read
project_common
end
def call
set_project_common
end
def reset
reset_project_common
end
private
def load_project
@project = Project.find_by_id(project_id)
end
def project_common_key
"v2-project-common:#{@project_id}"
end
def owner_id_key
"owner_id"
end
def name_key
"name"
end
def identifier_key
"identifier"
end
def visits_key
"visits"
end
def watchers_key
"watchers"
end
def praises_key
"praises"
end
def forks_key
"forks"
end
def issues_key
"issues"
end
def pullrequests_key
"pullrequests"
end
def project_common
$redis_cache.hgetall(project_common_key).blank? ? reset_project_common : $redis_cache.hgetall(project_common_key)
end
def set_project_common
if $redis_cache.hgetall(project_common_key).blank?
reset_project_common
return
end
if @owner_id.present?
if $redis_cache.hget(project_common_key, owner_id_key).nil?
reset_project_owner_id
else
$redis_cache.hset(project_common_key, owner_id_key, @owner_id)
end
end
if @name.present?
if $redis_cache.hget(project_common_key, name_key).nil?
reset_project_name
else
$redis_cache.hset(project_common_key, name_key, @name)
end
end
if @identifier.present?
if $redis_cache.hget(project_common_key, identifier_key).nil?
reset_project_identifier
else
$redis_cache.hset(project_common_key, identifier_key, @identifier)
end
end
if @visits.present?
if $redis_cache.hget(project_common_key, visits_key).nil?
reset_project_visits
else
$redis_cache.hincrby(project_common_key, visits_key, @visits)
Cache::V2::ProjectRankService.call(@project_id, {visits: @visits})
Cache::V2::ProjectDateRankService.call(@project_id, {visits: @visits})
end
end
if @watchers.present?
if $redis_cache.hget(project_common_key, watchers_key).nil?
reset_project_watchers
else
$redis_cache.hincrby(project_common_key, watchers_key, @watchers)
end
end
if @praises.present?
if $redis_cache.hget(project_common_key, praises_key).nil?
reset_project_praises
else
$redis_cache.hincrby(project_common_key, praises_key, @praises)
Cache::V2::ProjectRankService.call(@project_id, {praises: @praises})
Cache::V2::ProjectDateRankService.call(@project_id, {praises: @praises})
end
end
if @forks.present?
if $redis_cache.hget(project_common_key, forks_key).nil?
reset_project_forks
else
$redis_cache.hincrby(project_common_key, forks_key, @forks)
Cache::V2::ProjectRankService.call(@project_id, {forks: @forks})
Cache::V2::ProjectDateRankService.call(@project_id, {forks: @forks})
end
end
if @issues.present?
if $redis_cache.hget(project_common_key, issues_key).nil?
reset_project_issues
else
$redis_cache.hincrby(project_common_key, issues_key, @issues)
Cache::V2::ProjectRankService.call(@project_id, {issues: @issues})
Cache::V2::ProjectDateRankService.call(@project_id, {issues: @issues})
end
end
if @pullrequests.present?
if $redis_cache.hget(project_common_key, pullrequests_key).nil?
reset_project_pullrequests
else
$redis_cache.hincrby(project_common_key, pullrequests_key, @pullrequests)
Cache::V2::ProjectRankService.call(@project_id, {pullrequests: @pullrequests})
Cache::V2::ProjectDateRankService.call(@project_id, {pullrequests: @pullrequests})
end
end
$redis_cache.hgetall(project_common_key)
end
def reset_project_owner_id
$redis_cache.hset(project_common_key, owner_id_key, @project&.user_id)
end
def reset_project_name
$redis_cache.hset(project_common_key, name_key, @project&.name)
end
def reset_project_identifier
$redis_cache.hset(project_common_key, identifier_key, @project&.identifier)
end
def reset_project_visits
$redis_cache.hset(project_common_key, visits_key, @project&.visits)
end
def reset_project_watchers
$redis_cache.hset(project_common_key, watchers_key, Watcher.where(watchable_type: 'Project', watchable_id: @project_id).count)
end
def reset_project_praises
$redis_cache.hset(project_common_key, praises_key, PraiseTread.where(praise_tread_object_type: 'Project', praise_tread_object_id: @project_id).count)
end
def reset_project_forks
$redis_cache.hset(project_common_key, forks_key, ForkUser.where(project_id: @project_id).count)
end
def reset_project_issues
$redis_cache.hset(project_common_key, issues_key, Issue.where(project_id: @project_id).count)
end
def reset_project_pullrequests
$redis_cache.hset(project_common_key, pullrequests_key, PullRequest.where(project_id: @project_id).count)
end
def reset_project_common
load_project
$redis_cache.del(project_common_key)
reset_project_owner_id
reset_project_name
reset_project_identifier
reset_project_visits
reset_project_watchers
reset_project_praises
reset_project_forks
reset_project_issues
reset_project_pullrequests
$redis_cache.hgetall(project_common_key)
end
end

View File

@ -0,0 +1,50 @@
class Cache::V2::ProjectDateRankService < ApplicationService
attr_reader :project_id, :rank_date, :visits, :praises, :forks, :issues, :pullrequests
attr_accessor :project_common
def initialize(project_id, rank_date=Date.today, params={})
@project_id = project_id
@visits = params[:visits]
@praises = params[:praises]
@forks = params[:forks]
@issues = params[:issues]
@pullrequests = params[:pullrequests]
end
def read
project_rank
end
def call
set_project_rank
end
private
def project_rank_key
"v2-project-rank-#{rank_date.to_s}"
end
def project_rank
$redis_cache.zscore(project_rank_key, @project_id)
end
def set_project_rank
if @visits.present?
$redis_cache.zincrby(project_rank_key, @visits.to_i * 1, @project_id)
end
if @praises.present?
$redis_cache.zincrby(project_rank_key, @praises.to_i * 5, @project_id)
end
if @forks.present?
$redis_cache.zincrby(project_rank_key, @forks.to_i * 5, @project_id)
end
if @issues.present?
$redis_cache.zincrby(project_rank_key, @issues.to_i * 10, @project_id)
end
if @pullrequests.present?
$redis_cache.zincrby(project_rank_key, @pullrequests.to_i * 10, @project_id)
end
$redis_cache.zscore(project_rank_key, @project_id)
end
end

View File

@ -0,0 +1,71 @@
class Cache::V2::ProjectRankService < ApplicationService
attr_reader :project_id, :visits, :praises, :forks, :issues, :pullrequests
attr_accessor :project_common
def initialize(project_id, params={})
@project_id = project_id
@visits = params[:visits]
@praises = params[:praises]
@forks = params[:forks]
@issues = params[:issues]
@pullrequests = params[:pullrequests]
end
def read
project_rank
end
def call
set_project_rank
end
def reset
reset_project_rank
end
private
def load_project_common
@project_common = Cache::V2::ProjectCommonService.new(@project_id).read
end
def project_rank_key
"v2-project-rank"
end
def project_rank
$redis_cache.zscore(project_rank_key, @project_id).blank? ? reset_project_rank : $redis_cache.zscore(project_rank_key, @project_id)
end
def set_project_rank
if $redis_cache.zscore(project_rank_key, @project_id).blank?
reset_project_rank
return
end
if @visits.present?
$redis_cache.zincrby(project_rank_key, @visits.to_i * 1, @project_id)
end
if @praises.present?
$redis_cache.zincrby(project_rank_key, @praises.to_i * 5, @project_id)
end
if @forks.present?
$redis_cache.zincrby(project_rank_key, @forks.to_i * 5, @project_id)
end
if @issues.present?
$redis_cache.zincrby(project_rank_key, @issues.to_i * 10, @project_id)
end
if @pullrequests.present?
$redis_cache.zincrby(project_rank_key, @pullrequests.to_i * 10, @project_id)
end
$redis_cache.zscore(project_rank_key, @project_id)
end
def reset_project_rank
load_project_common
$redis_cache.zrem(project_rank_key, @project_id)
score = @project_common["visits"].to_i * 1 + @project_common["praises"].to_i * 5 + @project_common["forks"].to_i * 5 + @project_common["issues"].to_i * 10 + @project_common["pullrequests"].to_i * 10
$redis_cache.zincrby(project_rank_key, score, @project_id)
$redis_cache.zscore(project_rank_key, @project_id)
end
end

View File

@ -0,0 +1,183 @@
class Cache::V2::UserStatisticService < ApplicationService
attr_reader :user_id, :follow_count, :fork_count, :issue_count, :project_count, :project_language_count_key, :project_language_count, :project_praise_count, :project_watcher_count, :pullrequest_count
def initialize(user_id, params={})
@user_id = user_id
@follow_count = params[:follow_count]
@fork_count = params[:fork_count]
@issue_count = params[:issue_count]
@project_count = params[:project_count]
@project_language_count_key = params[:project_language_count_key]
@project_language_count = params[:project_language_count]
@project_praise_count = params[:project_praise_count]
@project_watcher_count = params[:project_watcher_count]
@pullrequest_count = params[:pullrequest_count]
end
def read
user_statistic
end
def call
set_user_statistic
end
def reset
reset_user_statistic
end
private
def user_statistic_key
"v2-user-statistic:#{@user_id}"
end
def follow_count_key
"follow-count"
end
def fork_count_key
"fork-count"
end
def issue_count_key
"issue-count"
end
def project_count_key
"project-count"
end
def project_language_key
"project-language"
end
def project_praise_count_key
"project-praise-count"
end
def project_watcher_count_key
"project-watcher-count"
end
def pullrequest_count_key
"pullrequest-count"
end
def user_statistic
$redis_cache.hgetall(user_statistic_key).blank? ? reset_user_statistic : $redis_cache.hgetall(user_statistic_key)
end
def set_user_statistic
if $redis_cache.hgetall(user_statistic_key).blank?
reset_user_statistic
return
end
if @follow_count.present?
if $redis_cache.hget(user_statistic_key, follow_count_key).nil?
reset_user_follow_count
else
$redis_cache.hincrby(user_statistic_key, follow_count_key, @follow_count)
end
end
if @fork_count.present?
if $redis_cache.hget(user_statistic_key, fork_count_key).nil?
reset_user_fork_count
else
$redis_cache.hincrby(user_statistic_key, fork_count_key, @fork_count)
end
end
if @issue_count.present?
if $redis_cache.hget(user_statistic_key, issue_count_key).nil?
reset_user_issue_count
else
$redis_cache.hincrby(user_statistic_key, issue_count_key, @issue_count)
end
end
if @project_count.present?
if $redis_cache.hget(user_statistic_key, project_count_key).nil?
reset_user_project_count
else
$redis_cache.hincrby(user_statistic_key, project_count_key, @project_count)
end
end
if @project_language_count_key.present? && project_language_count.present?
if $redis_cache.hget(user_statistic_key, project_language_key).nil?
reset_user_project_language
else
result = JSON.parse($redis_cache.hget(user_statistic_key, project_language_key))
result[@project_language_count_key] ||= 0
result[@project_language_count_key] += project_language_count.to_i
$redis_cache.hset(user_statistic_key, project_language_key, result.to_json)
end
end
if @project_praise_count.present?
if $redis_cache.hget(user_statistic_key, project_praise_count_key).nil?
reset_user_project_praise_count
else
$redis_cache.hincrby(user_statistic_key, project_praise_count_key, @project_praise_count)
end
end
if @project_watcher_count.present?
if $redis_cache.hget(user_statistic_key, project_watcher_count_key).nil?
reset_user_project_watcher_count
else
$redis_cache.hincrby(user_statistic_key, project_watcher_count_key, @project_watcher_count)
end
end
if @pullrequest_count.present?
if $redis_cache.hget(user_statistic_key, pullrequest_count_key).nil?
reset_user_pullrequest_count
else
$redis_cache.hincrby(user_statistic_key, pullrequest_count_key, @pullrequest_count)
end
end
$redis_cache.hgetall(user_statistic_key)
end
def reset_user_follow_count
$redis_cache.hset(user_statistic_key, follow_count_key, Watcher.where(watchable_type: 'User', watchable_id: @user_id).count)
end
def reset_user_fork_count
$redis_cache.hset(user_statistic_key, fork_count_key, ForkUser.joins(:project).where(projects: {user_id: @user_id}).count)
end
def reset_user_issue_count
$redis_cache.hset(user_statistic_key, issue_count_key, Issue.where(author_id: @user_id).count)
end
def reset_user_project_count
$redis_cache.hset(user_statistic_key, project_count_key, Project.where(user_id: @user_id).count)
end
def reset_user_project_language
$redis_cache.hset(user_statistic_key, project_language_key, Project.where(user_id: @user_id).joins(:project_language).group("project_languages.name").count.to_json)
end
def reset_user_project_praise_count
$redis_cache.hset(user_statistic_key, project_praise_count_key, PraiseTread.where(praise_tread_object_type: 'Project', praise_tread_object_id: Project.where(user_id: @user_id)).count)
end
def reset_user_project_watcher_count
$redis_cache.hset(user_statistic_key, project_watcher_count_key, Watcher.where(watchable_type: 'Project', watchable_id: Project.where(user_id: @user_id)).count)
end
def reset_user_pullrequest_count
$redis_cache.hset(user_statistic_key, pullrequest_count_key, PullRequest.where(user_id: @user_id).count)
end
def reset_user_statistic
$redis_cache.del(user_statistic_key)
reset_user_follow_count
reset_user_fork_count
reset_user_issue_count
reset_user_project_count
reset_user_project_language
reset_user_project_praise_count
reset_user_project_watcher_count
reset_user_pullrequest_count
$redis_cache.hgetall(user_statistic_key)
end
end