5
5
6
6
import * as buffer from 'buffer' ;
7
7
import { ApolloQueryResult , DocumentNode , FetchResult , MutationOptions , NetworkStatus , QueryOptions } from 'apollo-boost' ;
8
+ import LRUCache from 'lru-cache' ;
8
9
import * as vscode from 'vscode' ;
9
10
import { AuthenticationError , AuthProvider , GitHubServerType , isSamlError } from '../common/authentication' ;
10
11
import { COPILOT_ACCOUNTS , IComment , IReviewThread } from '../common/comment' ;
11
- import { Disposable } from '../common/lifecycle' ;
12
+ import { Disposable , disposeAll } from '../common/lifecycle' ;
12
13
import Logger from '../common/logger' ;
13
14
import { GitHubRemote , parseRemote } from '../common/remote' ;
14
15
import { ITelemetry } from '../common/telemetry' ;
@@ -43,6 +44,7 @@ import {
43
44
RevertPullRequestResponse ,
44
45
SuggestedActorsResponse ,
45
46
TimelineEventsResponse ,
47
+ UserResponse ,
46
48
ViewerPermissionResponse ,
47
49
} from './graphql' ;
48
50
import {
@@ -57,6 +59,7 @@ import {
57
59
PullRequestChecks ,
58
60
PullRequestReviewRequirement ,
59
61
RepoAccessAndMergeMethods ,
62
+ User ,
60
63
} from './interface' ;
61
64
import { IssueModel } from './issueModel' ;
62
65
import { LoggingOctokit } from './loggingOctokit' ;
@@ -76,6 +79,7 @@ import {
76
79
parseCombinedTimelineEvents ,
77
80
parseGraphQLIssue ,
78
81
parseGraphQLPullRequest ,
82
+ parseGraphQLUser ,
79
83
parseGraphQLViewerPermission ,
80
84
parseMergeMethod ,
81
85
parseMilestone ,
@@ -162,7 +166,13 @@ export class GitHubRepository extends Disposable {
162
166
protected _metadata : Promise < IMetadata > | undefined ;
163
167
public commentsController ?: vscode . CommentController ;
164
168
public commentsHandler ?: PRCommentControllerRegistry ;
165
- private _pullRequestModels = new Map < number , PullRequestModel > ( ) ;
169
+ private _pullRequestModelsByNumber : LRUCache < number , { model : PullRequestModel , disposables : vscode . Disposable [ ] } > = new LRUCache ( {
170
+ maxAge : 1000 * 60 * 60 * 4 /* 4 hours */ , stale : true , updateAgeOnGet : true ,
171
+ dispose : ( _key , value ) => {
172
+ disposeAll ( value . disposables ) ;
173
+ value . model . dispose ( ) ;
174
+ }
175
+ } ) ;
166
176
private _queriesSchema : any ;
167
177
private _areQueriesLimited : boolean = false ;
168
178
@@ -186,8 +196,12 @@ export class GitHubRepository extends Disposable {
186
196
return this . remote . equals ( repo . remote ) ;
187
197
}
188
198
189
- get pullRequestModels ( ) : Map < number , PullRequestModel > {
190
- return this . _pullRequestModels ;
199
+ getExistingPullRequestModel ( prNumber : number ) : PullRequestModel | undefined {
200
+ return this . _pullRequestModelsByNumber . get ( prNumber ) ?. model ;
201
+ }
202
+
203
+ get pullRequestModels ( ) : PullRequestModel [ ] {
204
+ return Array . from ( this . _pullRequestModelsByNumber . values ( ) . map ( value => value . model ) ) ;
191
205
}
192
206
193
207
public async ensureCommentsController ( ) : Promise < void > {
@@ -940,19 +954,26 @@ export class GitHubRepository extends Disposable {
940
954
}
941
955
942
956
createOrUpdatePullRequestModel ( pullRequest : PullRequest ) : PullRequestModel {
943
- let model = this . _pullRequestModels . get ( pullRequest . number ) ;
957
+ let model = this . _pullRequestModelsByNumber . get ( pullRequest . number ) ?. model ;
944
958
if ( model ) {
945
959
model . update ( pullRequest ) ;
946
960
} else {
947
961
model = new PullRequestModel ( this . _credentialStore , this . _telemetry , this , this . remote , pullRequest ) ;
962
+ const prModel = model ;
948
963
model . onDidInvalidate ( ( ) => this . getPullRequest ( pullRequest . number ) ) ;
949
- this . _pullRequestModels . set ( pullRequest . number , model ) ;
964
+ const disposables : vscode . Disposable [ ] = [ ] ;
965
+ disposables . push ( model . onDidChange ( ( ) => this . _onPullRequestModelChanged ( prModel ) ) ) ;
966
+ this . _pullRequestModelsByNumber . set ( pullRequest . number , { model, disposables } ) ;
950
967
this . _onDidAddPullRequest . fire ( model ) ;
951
968
}
952
969
953
970
return model ;
954
971
}
955
972
973
+ private _onPullRequestModelChanged ( model : PullRequestModel ) : void {
974
+ this . _onDidChangePullRequests . fire ( [ model ] ) ;
975
+ }
976
+
956
977
async createPullRequest ( params : OctokitCommon . PullsCreateParams ) : Promise < PullRequestModel > {
957
978
try {
958
979
Logger . debug ( `Create pull request - enter` , this . id ) ;
@@ -1233,6 +1254,27 @@ export class GitHubRepository extends Disposable {
1233
1254
return ret ;
1234
1255
}
1235
1256
1257
+ async resolveUser ( login : string ) : Promise < User | undefined > {
1258
+ Logger . debug ( `Fetch user ${ login } ` , this . id ) ;
1259
+ const { query, schema } = await this . ensure ( ) ;
1260
+
1261
+ try {
1262
+ const { data } = await query < UserResponse > ( {
1263
+ query : schema . GetUser ,
1264
+ variables : {
1265
+ login,
1266
+ } ,
1267
+ } ) ;
1268
+ return parseGraphQLUser ( data , this ) ;
1269
+ } catch ( e ) {
1270
+ // Ignore cases where the user doesn't exist
1271
+ if ( ! ( e . message as ( string | undefined ) ) ?. startsWith ( 'GraphQL error: Could not resolve to a User with the login of' ) ) {
1272
+ Logger . warn ( e . message ) ;
1273
+ }
1274
+ }
1275
+ return undefined ;
1276
+ }
1277
+
1236
1278
async getAssignableUsers ( ) : Promise < IAccount [ ] > {
1237
1279
Logger . debug ( `Fetch assignable users - enter` , this . id ) ;
1238
1280
const { query, remote, schema } = await this . ensure ( ) ;
@@ -1554,9 +1596,9 @@ export class GitHubRepository extends Disposable {
1554
1596
return [ event . source . url , event ] ;
1555
1597
} ) ) ;
1556
1598
1557
- for ( const model of this . _pullRequestModels . values ( ) ) {
1558
- if ( crossRefs . has ( model . html_url ) ) {
1559
- crossRefs . delete ( model . html_url ) ;
1599
+ for ( const pr of this . _pullRequestModelsByNumber . values ( ) ) {
1600
+ if ( crossRefs . has ( pr . model . html_url ) ) {
1601
+ crossRefs . delete ( pr . model . html_url ) ;
1560
1602
}
1561
1603
}
1562
1604
const oldEvents = issueModel . timelineEvents ;
0 commit comments