@@ -73,6 +73,40 @@ func (u *GitIdentityUsecase) gitClienter(identity *db.GitIdentity) domain.GitCli
7373 return gitpkg .NewCachedGitClient (inner , u .repoCache , identity .UserID .String ()+ ":" + identity .ID .String ())
7474}
7575
76+ // prefetchRepositories 异步预拉取仓库列表以预热缓存
77+ func (u * GitIdentityUsecase ) prefetchRepositories (identity * db.GitIdentity ) {
78+ go func () {
79+ defer func () {
80+ if r := recover (); r != nil {
81+ u .logger .Warn ("prefetch: panic recovered" , "error" , r , "identity_id" , identity .ID )
82+ }
83+ }()
84+ ctx , cancel := context .WithTimeout (context .Background (), 60 * time .Second )
85+ defer cancel ()
86+ if _ , err := u .fetchRepositories (ctx , identity , false ); err != nil {
87+ u .logger .WarnContext (ctx , "prefetch: failed to fetch repositories" , "error" , err , "identity_id" , identity .ID )
88+ }
89+ }()
90+ }
91+
92+ // fetchRepositories 拉取 identity 关联的仓库列表
93+ func (u * GitIdentityUsecase ) fetchRepositories (ctx context.Context , identity * db.GitIdentity , flush bool ) ([]domain.AuthRepository , error ) {
94+ client := u .gitClienter (identity )
95+ if client == nil {
96+ return nil , nil
97+ }
98+ token , err := u .tokenProvider .GetToken (ctx , identity .ID )
99+ if err != nil {
100+ return nil , fmt .Errorf ("get token: %w" , err )
101+ }
102+ return client .Repositories (ctx , & domain.RepositoryOptions {
103+ Token : token ,
104+ InstallID : identity .InstallationID ,
105+ IsOAuth : identity .OauthRefreshToken != "" ,
106+ Flush : flush ,
107+ })
108+ }
109+
76110// Get 获取单个 Git 身份认证(仅限当前用户)
77111func (u * GitIdentityUsecase ) Get (ctx context.Context , uid uuid.UUID , id uuid.UUID , flush bool ) (* domain.GitIdentity , error ) {
78112 identity , err := u .repo .GetByUserID (ctx , uid , id )
@@ -85,24 +119,12 @@ func (u *GitIdentityUsecase) Get(ctx context.Context, uid uuid.UUID, id uuid.UUI
85119 }
86120 gi := cvt .From (identity , & domain.GitIdentity {})
87121
88- if client := u .gitClienter (identity ); client != nil {
89- token , err := u .tokenProvider .GetToken (ctx , identity .ID )
90- if err != nil {
91- u .logger .WarnContext (ctx , "failed to get token" , "error" , err , "platform" , identity .Platform , "identity_id" , identity .ID )
92- return gi , nil
93- }
94- repos , err := client .Repositories (ctx , & domain.RepositoryOptions {
95- Token : token ,
96- InstallID : identity .InstallationID ,
97- IsOAuth : identity .OauthRefreshToken != "" ,
98- Flush : flush ,
99- })
100- if err != nil {
101- u .logger .WarnContext (ctx , "failed to get authorized repositories" , "error" , err , "platform" , identity .Platform , "identity_id" , identity .ID )
102- return gi , nil
103- }
104- gi .AuthorizedRepositories = repos
122+ repos , err := u .fetchRepositories (ctx , identity , flush )
123+ if err != nil {
124+ u .logger .WarnContext (ctx , "failed to get authorized repositories" , "error" , err , "platform" , identity .Platform , "identity_id" , identity .ID )
125+ return gi , nil
105126 }
127+ gi .AuthorizedRepositories = repos
106128
107129 return gi , nil
108130}
@@ -114,6 +136,7 @@ func (u *GitIdentityUsecase) Add(ctx context.Context, uid uuid.UUID, req *domain
114136 u .logger .ErrorContext (ctx , "failed to create git identity" , "error" , err , "user_id" , uid )
115137 return nil , err
116138 }
139+ u .prefetchRepositories (identity )
117140 return cvt .From (identity , & domain.GitIdentity {}), nil
118141}
119142
@@ -125,6 +148,9 @@ func (u *GitIdentityUsecase) Update(ctx context.Context, uid uuid.UUID, req *dom
125148 }
126149 u .tokenProvider .ClearCache (req .ID )
127150 u .repoCache .Delete (uid .String () + ":" + req .ID .String ())
151+ if identity , err := u .repo .Get (ctx , req .ID ); err == nil {
152+ u .prefetchRepositories (identity )
153+ }
128154 return nil
129155}
130156
0 commit comments