Compare commits

...

11 Commits

Author SHA1 Message Date
xxq250 513036597d 缓存调整 2025-01-10 09:08:47 +08:00
yystopf 52d73ce3ff fix: organizations and pull cache view 2024-12-27 17:15:00 +08:00
xxq250 4c9c746356 fixed views cache 2024-12-27 17:06:46 +08:00
xxq250 bc836e5a1c fixed user cache 2024-12-27 16:45:19 +08:00
yystopf 2457e4a6ad fix: 更新cache方式 2024-12-27 15:08:52 +08:00
yystopf 60edacd97a fix 2024-12-27 08:33:19 +08:00
yystopf 04070f352d fix 2024-12-26 17:28:52 +08:00
yystopf 02aa93db0f fix 2024-12-26 16:25:05 +08:00
yystopf f2044696df fix 2024-12-26 16:20:49 +08:00
yystopf a6cafebc9e fix 2024-12-26 16:18:08 +08:00
yystopf 2205261661 新增: 五个接口走缓存 2024-12-26 16:09:17 +08:00
11 changed files with 219 additions and 125 deletions

View File

@ -379,7 +379,9 @@ class ApplicationController < ActionController::Base
uid_logger("user setup start: autologin_user is #{autologin_user}")
# 多浏览器退出账号时token不存在处理
if current_domain_session && autologin_user.nil?
autologin_user = (User.active.find(current_domain_session) rescue nil)
autologin_user = Rails.cache.fetch("ApplicationController::find_current_user:#{current_domain_session}", expires_in: 30.minutes) do
(User.active.find(current_domain_session) rescue nil)
end
set_autologin_cookie(autologin_user) if autologin_user.present?
end
autologin_user

View File

@ -27,7 +27,9 @@ module LaboratoryHelper
end
def default_yun_session
laboratory ||= (Laboratory.find_by_subdomain(request.subdomain) || Laboratory.find(1))
laboratory ||= Rails.cache.fetch("LaboratoryHelper::default_yun_session:#{request.subdomain}:1") do
(Laboratory.find_by_subdomain(request.subdomain) || Laboratory.find(1))
end
@_default_yun_session = "#{laboratory.try(:identifier).split('.').first}_user_id"
end

View File

@ -311,40 +311,79 @@ class ProjectsController < ApplicationController
end
def simple
if !@project.common? && @project&.repository&.mirror&.waiting?
gitea_result = $gitea_client.get_repos_by_owner_repo(@project&.owner&.login, @project&.identifier) rescue nil
if gitea_result.present? && !gitea_result["empty"]
@project&.update_columns(gpid: gitea_result["id"])
@project&.repository&.mirror&.succeeded!
project_id = @project&.id
user_id = @project&.owner&.id
Rails.logger.info "############ mirror project_id,user_id: #{project_id},#{user_id} ############"
OpenProjectDevOpsJob.set(wait: 5.seconds).perform_later(project_id, user_id) if project_id.present? && user_id.present?
UpdateProjectTopicJob.set(wait: 1.seconds).perform_later(project_id) if project_id.present?
Rails.logger.info "############ mirror status: #{@project&.repository&.mirror&.status} ############"
result = Rails.cache.fetch("ProjectsController::simple:#{@project&.owner&.login}:#{@project&.identifier}") do
if !@project.common? && @project&.repository&.mirror&.waiting?
gitea_result = $gitea_client.get_repos_by_owner_repo(@project&.owner&.login, @project&.identifier) rescue nil
if gitea_result.present? && !gitea_result["empty"]
@project&.update_columns(gpid: gitea_result["id"])
@project&.repository&.mirror&.succeeded!
project_id = @project&.id
user_id = @project&.owner&.id
Rails.logger.info "############ mirror project_id,user_id: #{project_id},#{user_id} ############"
OpenProjectDevOpsJob.set(wait: 5.seconds).perform_later(project_id, user_id) if project_id.present? && user_id.present?
UpdateProjectTopicJob.set(wait: 1.seconds).perform_later(project_id) if project_id.present?
Rails.logger.info "############ mirror status: #{@project&.repository&.mirror&.status} ############"
end
elsif !@project.common? && @project&.repository&.mirror&.failed?
# 导入失败的项目标记 project.status=0, 在列表中不显示
@project&.update_columns(status: 0) if @project&.status == 1
# Rails.logger.info "############ mirror status: #{@project&.repository&.mirror&.status}"
# Gitea::Repository::DeleteService.new(@project.owner, @project.identifier,current_user.gitea_token).call
# @project.destroy!
# @project.forked_projects.update_all(forked_from_project_id: nil)
# # 如果该项目有所属的项目分类以及为私有项目,需要更新对应数量
# @project.project_category.decrement!(:private_projects_count, 1) if @project.project_category.present? && !@project.is_public
# return render_error("导入失败,请重试!")
end
# 为了缓存活跃项目的基本信息,后续删除
Cache::V2::ProjectCommonService.new(@project.id).read
# 项目名称,标识,所有者变化时重置缓存
project_common = $redis_cache.hgetall("v2-project-common:#{@project.id}")
if project_common.present?
if project_common["name"] != @project.name || project_common["identifier"] != @project.identifier || project_common["owner_id"] != @project.user_id
Cache::V2::ProjectCommonService.new(@project.id).reset
end
end
elsif !@project.common? && @project&.repository&.mirror&.failed?
# 导入失败的项目标记 project.status=0, 在列表中不显示
@project&.update_columns(status: 0) if @project&.status == 1
# Rails.logger.info "############ mirror status: #{@project&.repository&.mirror&.status}"
# Gitea::Repository::DeleteService.new(@project.owner, @project.identifier,current_user.gitea_token).call
# @project.destroy!
# @project.forked_projects.update_all(forked_from_project_id: nil)
# # 如果该项目有所属的项目分类以及为私有项目,需要更新对应数量
# @project.project_category.decrement!(:private_projects_count, 1) if @project.project_category.present? && !@project.is_public
# return render_error("导入失败,请重试!")
end
# 为了缓存活跃项目的基本信息,后续删除
Cache::V2::ProjectCommonService.new(@project.id).read
# 项目名称,标识,所有者变化时重置缓存
project_common = $redis_cache.hgetall("v2-project-common:#{@project.id}")
if project_common.present?
if project_common["name"] != @project.name || project_common["identifier"] != @project.identifier || project_common["owner_id"] != @project.user_id
Cache::V2::ProjectCommonService.new(@project.id).reset
repo = Repository.includes(:mirror).select(:id, :is_mirror, :mirror_url, :source_clone_url).find_by(project: @project)
tmp_json = {}
unless @project.common?
tmp_json = tmp_json.merge({
is_mirror: repo.is_mirror ? true : false,
mirror_status: repo.mirror_status,
mirror_num: repo.mirror_num,
mirror_url: repo.remote_mirror_url,
first_sync: repo.first_sync?
})
end
tmp_json = tmp_json.merge({
identifier: render_identifier(@project),
name: @project.name,
platform: @project.platform,
id: @project.id,
repo_id: repo.id,
open_devops: (current_user.blank? || current_user.is_a?(AnonymousUser)) ? false : @project.open_devops?,
type: @project.numerical_for_project_type,
author: render_owner(@project),
project_category_id: @project.project_category_id,
project_language_id: @project.project_language_id,
license_id: @project.license_id,
jianmu_devops: jianmu_devops_code(@project, current_user),
jianmu_devops_url: jianmu_devops_url,
cloud_ide_saas_url: cloud_ide_saas_url(current_user),
open_blockchain: Site.has_blockchain? && @project.use_blockchain,
has_dataset: @project.project_dataset.present?,
open_portrait: @project.open_portrait,
ignore_id: @project.ignore_id
}).compact
tmp_json
end
json_response(@project, current_user)
render json: result
end
def recommend

View File

@ -12,21 +12,24 @@ class PullRequestsController < ApplicationController
def index
# @issues = Gitea::PullRequest::ListService.new(@user,@repository.try(:identifier)).call #通过gitea获取
issues = @project.issues.issue_pull_request.issue_index_includes.includes(pull_request: :user)
issues = issues.where(is_private: false) unless current_user.present? && (current_user.admin? || @project.member?(current_user))
@all_issues = issues.distinct
@filter_issues = @all_issues
@filter_issues = @filter_issues.where("issues.subject LIKE ? OR issues.description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
@open_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::OPEN})
@close_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::CLOSED})
@merged_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::MERGED})
@user_admin_or_member = current_user.present? && (current_user.admin || @project.member?(current_user))
@user_admin_or_developer = current_user.present? && (current_user.admin || @project.all_developers.include?(current_user))
@all_issues, @filter_issues, @open_issues, @close_issues, @merged_issues, @user_admin_or_member, @user_admin_or_developer, @issues_size, @issues = Rails.cache.fetch("PullRequestsController:index:#{@project&.owner&.login}:#{@project.identifier}:#{params.to_unsafe_h}:#{current_user.id}") do
# @issues = Gitea::PullRequest::ListService.new(@user,@repository.try(:identifier)).call #通过gitea获取
issues = @project.issues.issue_pull_request.issue_index_includes.includes(pull_request: :user)
issues = issues.where(is_private: false) unless current_user.present? && (current_user.admin? || @project.member?(current_user))
all_issues = issues.distinct
filter_issues = all_issues
filter_issues = filter_issues.where("issues.subject LIKE ? OR issues.description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
open_issues = filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::OPEN})
close_issues = filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::CLOSED})
merged_issues = filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::MERGED})
user_admin_or_member = current_user.present? && (current_user.admin || @project.member?(current_user))
user_admin_or_developer = current_user.present? && (current_user.admin || @project.all_developers.include?(current_user))
issues = Issues::ListQueryService.call(issues,params.delete_if{|k,v| v.blank?}, "PullRequest")
scopes = Issues::ListQueryService.call(issues,params.delete_if{|k,v| v.blank?}, "PullRequest")
@issues_size = scopes.size
@issues = paginate(scopes)
[all_issues.to_a, filter_issues.to_a, open_issues.to_a, close_issues.to_a, merged_issues.to_a, user_admin_or_member, user_admin_or_developer, issues.size, paginate(issues).to_a]
end
end
def new
@ -344,4 +347,8 @@ class PullRequestsController < ApplicationController
def check_menu_authorize
return render_not_found unless @project.has_menu_permission("pulls")
end
def to_query(hash)
hash.map { |key, value| "#{key}=#{value}" }.join('&')
end
end

View File

@ -1,33 +1,43 @@
class Users::OrganizationsController < Users::BaseController
def index
if current_user.logged?
logged_organizations_sql = observed_user.organizations.with_visibility(%w(common limited)).to_sql
privacy_organizations_sql = observed_user.organizations.with_visibility("privacy").joins(:organization_users).where(organization_users: {user_id: current_user.id}).to_sql
@organizations = Organization.from("( #{ logged_organizations_sql } UNION #{ privacy_organizations_sql } ) AS users")
else
@organizations = observed_user.organizations.with_visibility("common")
@page = params[:page].to_i.zero? ? 1 : params[:page].to_i
@limit = params[:limit] || params[:per_page]
@limit = (@limit.to_i.zero? || @limit.to_i > 20) ? 20 : @limit.to_i
@home_top_ids, @organizations = Rails.cache.fetch("Users::OrganizationsController:index:#{@page}:#{@limit}:#{current_user.id}:#{sort_by}:#{sort_direction}:#{params[:search]}", expires_in: 5.minutes) do
if current_user.logged?
logged_organizations_sql = observed_user.organizations.with_visibility(%w(common limited)).to_sql
privacy_organizations_sql = observed_user.organizations.with_visibility("privacy").joins(:organization_users).where(organization_users: {user_id: current_user.id}).to_sql
@organizations = Organization.from("( #{ logged_organizations_sql } UNION #{ privacy_organizations_sql } ) AS users")
else
@organizations = observed_user.organizations.with_visibility("common")
end
@organizations = @organizations.ransack(login_cont: params[:search]).result if params[:search].present?
@home_top_ids = @organizations.joins(:home_top_settings).where(home_top_settings: {user_id: observed_user.id}).order("home_top_settings.created_at asc").pluck(:id)
if @home_top_ids.present?
@organizations = @organizations.joins(:organization_extension).order("FIELD(users.id, #{@home_top_ids.join(",")}) desc, organization_extensions.#{sort_by} #{sort_direction}")
else
@organizations = @organizations.joins(:organization_extension).order("organization_extensions.#{sort_by} #{sort_direction}")
end
@organizations = kaminari_paginate(@organizations.includes([projects: :members], :organization_extension))
@total_count= @organizations.total_count
[@home_top_ids, @organizations.to_a, @total_count]
end
@organizations = @organizations.ransack(login_cont: params[:search]).result if params[:search].present?
@home_top_ids = @organizations.joins(:home_top_settings).where(home_top_settings: {user_id: observed_user.id}).order("home_top_settings.created_at asc").pluck(:id)
if @home_top_ids.present?
@organizations = @organizations.joins(:organization_extension).order("FIELD(users.id, #{@home_top_ids.join(",")}) desc, organization_extensions.#{sort_by} #{sort_direction}")
else
@organizations = @organizations.joins(:organization_extension).order("organization_extensions.#{sort_by} #{sort_direction}")
end
@organizations = kaminari_paginate(@organizations)
end
private
def sort_by
OrganizationExtension.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
@sort_by = OrganizationExtension.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
@sort_by
end
def sort_direction
%w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
@sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
@sort_direction
end
end

View File

@ -2,10 +2,16 @@ class Users::ProjectsController < Users::BaseController
skip_before_action :check_observed_user_exists!, only: [:search]
def index
projects = Users::ProjectService.new(observed_user, query_params).call
@count = projects.count
@projects = paginate(projects.includes(:project_score, owner: { user_extension: :school }), special: observed_user.is_teacher?)
cached_data = Rails.cache.read("Users::ProjectsController:index:#{params[:page]}:#{params[:limit]}:#{query_params[:category]}:#{query_params[:status]}:#{query_params[:sort_direction]}:#{query_params[:topic_name]}")
unless cached_data
projects = Users::ProjectService.new(observed_user, query_params).call
data_to_cache = paginate(projects.includes(:project_score, owner: { user_extension: :school }), special: observed_user.is_teacher?)
Rails.cache.write("Users::ProjectsController:index:#{params[:page]}:#{params[:limit]}:#{query_params[:category]}:#{query_params[:status]}:#{query_params[:sort_direction]}:#{query_params[:topic_name]}", data_to_cache, expires_in: 10.minutes)
# 缓存为空时执行API请求等操作
end
@projects = cached_data
@count = @projects.total_count
end
def search

View File

@ -407,10 +407,22 @@ class UsersController < ApplicationController
end
def projects
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
limit = (params[:limit].to_i.zero? || params[:limit].to_i > 9999) ? 9999 : params[:limit].to_i
is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == @user.id)
scope, @home_top_ids = Projects::ListMyQuery.call(params, @user,is_current_admin_user)
@total_count = scope.size
@projects = kaminari_unlimit_paginate(scope)
@scope, @home_top_ids = Rails.cache.fetch("UsersControllers::projects:#{page}:#{limit}:#{current_user.id}:scope") do
Projects::ListMyQuery.call(params, @user,is_current_admin_user)
end
@total_count = Rails.cache.fetch("UsersControllers::projects:#{page}:#{limit}:#{current_user.id}:total_count") do
@scope.count
end
@projects = Rails.cache.fetch("UsersControllers::projects:#{page}:#{limit}:#{current_user.id}:projects") do
kaminari_unlimit_paginate(@scope).to_a
end
end
@ -713,7 +725,9 @@ class UsersController < ApplicationController
private
def load_user
@user = User.find_by_login(params[:id]) || User.find_by(id: params[:id])
@user = Rails.cache.fetch("UsersControllers::load_user:#{params[:id]}") do
User.find_by_login(params[:id]) || User.find_by(id: params[:id])
end
clear_user_cookie unless @user.present?
end

View File

@ -1,19 +1,19 @@
# == Schema Information
#
# Table name: tokens
#
# id :integer not null, primary key
# user_id :integer default("0"), not null
# action :string(30) default(""), not null
# value :string(40) default(""), not null
# created_on :datetime not null
#
# Indexes
#
# index_tokens_on_user_id (user_id)
# tokens_value (value) UNIQUE
#
# == Schema Information
#
# Table name: tokens
#
# id :integer not null, primary key
# user_id :integer default("0"), not null
# action :string(30) default(""), not null
# value :string(40) default(""), not null
# created_on :datetime not null
#
# Indexes
#
# index_tokens_on_user_id (user_id)
# tokens_value (value) UNIQUE
#
#
@ -50,13 +50,17 @@ class Token < ActiveRecord::Base
token = Token.create(:user => user, :action => type)
Rails.logger.info "###### Token.get_token_from_user is nul and agine create token: #{token&.value}"
else
token.update_attribute(:created_on, Time.now)
Rails.cache.fetch("user::update::created_on::#{user.id}",:expires_in => 10.minutes) do
token.update_attribute(:created_on, Time.now)
end
end
token
end
def self.get_token_from_user(user, action)
token = Token.where(:action => action, :user_id => user).first
token = Rails.cache.fetch("Token::get_token_from_user:#{user.id}:1", :expires_in => 10.minutes) do
Token.where(:action => action, :user_id => user).first
end
Rails.logger.info "###### self.get_token_from_user query result: #{token&.value}"
unless token
token = Token.create!(user_id: user.id, action: action)

View File

@ -16,36 +16,42 @@ json.pr_need @project.owner.class == User ? false : @project.owner&.cla.try(:pr_
json.issues do
json.array! @issues.to_a do |issue|
pr = issue.pull_request
json.pull_request_id pr.id
json.pull_request_number pr.gitea_number
json.pull_request_status pr.status
json.pull_request_head pr.head
json.pull_request_base pr.base
json.pull_request_staus pr.status == 1 ? "merged" : (pr.status == 2 ? "closed" : "open")
json.is_original pr.is_original
json.fork_project_id pr.fork_project_id
json.fork_project_identifier pr.fork_project.present? ? pr&.fork_project&.identifier : pr.fork_project_identifier
json.fork_project_user pr.fork_project.present? ? pr&.fork_project&.owner.try(:login) : pr.fork_project_owner
json.fork_project_user_name pr.fork_project.present? ? pr&.fork_project&.owner.try(:show_real_name) : User.find_by(login: pr.fork_project_owner).try(:show_real_name)
json.reviewers pr.reviewers.pluck(:login)
json.id issue.id
json.name issue.subject
json.pr_time time_from_now(pr.status == 1 ? pr.updated_at : issue.updated_on)
json.pr_full_time pr.status == 1 ? pr.updated_at : issue.updated_on
json.pr_created_unix pr.created_at.to_i
json.assign_user_name issue.get_assign_user.try(:show_real_name)
json.assign_user_login issue.get_assign_user.try(:login)
json.author_name issue.user.blank?? "已注销": issue.user.show_real_name
json.author_login issue.user.try(:login)
json.avatar_url issue.user.blank?? "images/account/del.svg" : url_to_avatar(issue.user)
json.priority issue.priority.try(:name)
json.version issue.version.try(:name)
json.journals_count issue.get_journals_size
json.issue_tags issue.get_issue_tags
json.attached_issues pr.attached_issues.each do |issue|
json.(issue, :id, :subject, :project_issues_index)
end
json.cache! ['v1', issue, pr], expires_in: 10.minutes do
json.pull_request_id pr.id
json.pull_request_number pr.gitea_number
json.pull_request_status pr.status
json.pull_request_head pr.head
json.pull_request_base pr.base
json.pull_request_staus pr.status == 1 ? "merged" : (pr.status == 2 ? "closed" : "open")
json.is_original pr.is_original
json.fork_project_id pr.fork_project_id
json.fork_project_identifier pr.fork_project.present? ? pr&.fork_project&.identifier : pr.fork_project_identifier
json.fork_project_user pr.fork_project.present? ? pr&.fork_project&.owner.try(:login) : pr.fork_project_owner
json.fork_project_user_name pr.fork_project.present? ? pr&.fork_project&.owner.try(:show_real_name) : User.find_by(login: pr.fork_project_owner).try(:show_real_name)
json.reviewers pr.reviewers.pluck(:login)
json.id issue.id
json.name issue.subject
json.pr_time time_from_now(pr.status == 1 ? pr.updated_at : issue.updated_on)
json.pr_full_time pr.status == 1 ? pr.updated_at : issue.updated_on
json.pr_created_unix pr.created_at.to_i
json.assign_user_name issue.get_assign_user.try(:show_real_name)
json.assign_user_login issue.get_assign_user.try(:login)
json.author_name issue.user.blank?? "已注销": issue.user.show_real_name
json.author_login issue.user.try(:login)
json.avatar_url issue.user.blank?? "images/account/del.svg" : url_to_avatar(issue.user)
json.priority issue.priority.try(:name)
json.version issue.version.try(:name)
json.journals_count issue.get_journals_size
json.issue_tags issue.get_issue_tags
json.attached_issues pr.attached_issues.each do |issue|
json.(issue, :id, :subject, :project_issues_index)
end
end
end
end

View File

@ -1,5 +1,7 @@
json.total_count @organizations.total_count
json.total_count @total_count
json.organizations @organizations do |organization|
json.partial! "/organizations/organizations/detail", organization: organization
json.cache! ['v1', organization], expires_in: 10.minutes do
json.partial! "/organizations/organizations/detail", organization: organization
end
json.is_home_top @home_top_ids.include?(organization.id)
end

View File

@ -1,5 +1,7 @@
json.count @total_count
json.projects @projects do |project|
json.partial! '/projects/project_detail', project: project
json.cache! ['v1', project], expires_in: 10.minutes do
json.partial! '/projects/project_detail', project: project
end
json.is_home_top @home_top_ids.include?(project.id)
end