@@ -8,6 +8,7 @@ import { Redis } from 'ioredis';
88import { INDEX_CACHE_DIR } from './constants.js' ;
99import { env } from './env.js' ;
1010import { cloneRepository , fetchRepository , isPathAValidGitRepoRoot , unsetGitConfig , upsertGitConfig } from './git.js' ;
11+ import { PromClient } from './promClient.js' ;
1112import { repoMetadataSchema , RepoWithConnections , Settings } from "./types.js" ;
1213import { getAuthCredentialsForRepo , getRepoPath , getShardPrefix , groupmqLifecycleExceptionWrapper , measure } from './utils.js' ;
1314import { indexGitRepository } from './zoekt.js' ;
@@ -43,6 +44,7 @@ export class RepoIndexManager {
4344 private db : PrismaClient ,
4445 private settings : Settings ,
4546 redis : Redis ,
47+ private promClient : PromClient ,
4648 ) {
4749 this . queue = new Queue < JobPayload > ( {
4850 redis,
@@ -73,7 +75,7 @@ export class RepoIndexManager {
7375 this . interval = setInterval ( async ( ) => {
7476 await this . scheduleIndexJobs ( ) ;
7577 await this . scheduleCleanupJobs ( ) ;
76- } , 1000 * 5 ) ;
78+ } , this . settings . reindexRepoPollingIntervalMs ) ;
7779
7880 this . worker . run ( ) ;
7981 }
@@ -135,7 +137,7 @@ export class RepoIndexManager {
135137 }
136138 }
137139 ] ,
138- }
140+ } ,
139141 } ) ;
140142
141143 if ( reposToIndex . length > 0 ) {
@@ -213,6 +215,9 @@ export class RepoIndexManager {
213215 } ,
214216 jobId : job . id ,
215217 } ) ;
218+
219+ const jobTypeLabel = getJobTypePrometheusLabel ( type ) ;
220+ this . promClient . pendingRepoIndexJobs . inc ( { repo : job . repo . name , type : jobTypeLabel } ) ;
216221 }
217222 }
218223
@@ -243,6 +248,10 @@ export class RepoIndexManager {
243248 }
244249 } ) ;
245250
251+ const jobTypeLabel = getJobTypePrometheusLabel ( jobType ) ;
252+ this . promClient . pendingRepoIndexJobs . dec ( { repo : job . data . repoName , type : jobTypeLabel } ) ;
253+ this . promClient . activeRepoIndexJobs . inc ( { repo : job . data . repoName , type : jobTypeLabel } ) ;
254+
246255 const abortController = new AbortController ( ) ;
247256 const signalHandler = ( ) => {
248257 logger . info ( `Received shutdown signal, aborting...` ) ;
@@ -378,6 +387,8 @@ export class RepoIndexManager {
378387 }
379388 } ) ;
380389
390+ const jobTypeLabel = getJobTypePrometheusLabel ( jobData . type ) ;
391+
381392 if ( jobData . type === RepoIndexingJobType . INDEX ) {
382393 const repo = await this . db . repo . update ( {
383394 where : { id : jobData . repoId } ,
@@ -395,6 +406,10 @@ export class RepoIndexManager {
395406
396407 logger . info ( `Completed cleanup job ${ job . data . jobId } for repo ${ repo . name } (id: ${ repo . id } )` ) ;
397408 }
409+
410+ // Track metrics for successful job
411+ this . promClient . activeRepoIndexJobs . dec ( { repo : job . data . repoName , type : jobTypeLabel } ) ;
412+ this . promClient . repoIndexJobSuccessTotal . inc ( { repo : job . data . repoName , type : jobTypeLabel } ) ;
398413 } ) ;
399414
400415 private onJobFailed = async ( job : Job < JobPayload > ) =>
@@ -404,6 +419,8 @@ export class RepoIndexManager {
404419 const attempt = job . attemptsMade + 1 ;
405420 const wasLastAttempt = attempt >= job . opts . attempts ;
406421
422+ const jobTypeLabel = getJobTypePrometheusLabel ( job . data . type ) ;
423+
407424 if ( wasLastAttempt ) {
408425 const { repo } = await this . db . repoIndexingJob . update ( {
409426 where : { id : job . data . jobId } ,
@@ -415,29 +432,38 @@ export class RepoIndexManager {
415432 select : { repo : true }
416433 } ) ;
417434
435+ this . promClient . activeRepoIndexJobs . dec ( { repo : job . data . repoName , type : jobTypeLabel } ) ;
436+ this . promClient . repoIndexJobFailTotal . inc ( { repo : job . data . repoName , type : jobTypeLabel } ) ;
437+
418438 logger . error ( `Failed job ${ job . data . jobId } for repo ${ repo . name } (id: ${ repo . id } ). Attempt ${ attempt } / ${ job . opts . attempts } . Failing job.` ) ;
419439 } else {
420440 const repo = await this . db . repo . findUniqueOrThrow ( {
421441 where : { id : job . data . repoId } ,
422442 } ) ;
423443
444+ this . promClient . repoIndexJobReattemptsTotal . inc ( { repo : job . data . repoName , type : jobTypeLabel } ) ;
445+
424446 logger . warn ( `Failed job ${ job . data . jobId } for repo ${ repo . name } (id: ${ repo . id } ). Attempt ${ attempt } / ${ job . opts . attempts } . Retrying.` ) ;
425447 }
426448 } ) ;
427449
428450 private onJobStalled = async ( jobId : string ) =>
429451 groupmqLifecycleExceptionWrapper ( 'onJobStalled' , logger , async ( ) => {
430452 const logger = createJobLogger ( jobId ) ;
431- const { repo } = await this . db . repoIndexingJob . update ( {
453+ const { repo, type } = await this . db . repoIndexingJob . update ( {
432454 where : { id : jobId } ,
433455 data : {
434456 status : RepoIndexingJobStatus . FAILED ,
435457 completedAt : new Date ( ) ,
436458 errorMessage : 'Job stalled' ,
437459 } ,
438- select : { repo : true }
460+ select : { repo : true , type : true }
439461 } ) ;
440462
463+ const jobTypeLabel = getJobTypePrometheusLabel ( type ) ;
464+ this . promClient . activeRepoIndexJobs . dec ( { repo : repo . name , type : jobTypeLabel } ) ;
465+ this . promClient . repoIndexJobFailTotal . inc ( { repo : repo . name , type : jobTypeLabel } ) ;
466+
441467 logger . error ( `Job ${ jobId } stalled for repo ${ repo . name } (id: ${ repo . id } )` ) ;
442468 } ) ;
443469
@@ -453,4 +479,6 @@ export class RepoIndexManager {
453479 await this . worker . close ( ) ;
454480 await this . queue . close ( ) ;
455481 }
456- }
482+ }
483+
484+ const getJobTypePrometheusLabel = ( type : RepoIndexingJobType ) => type === RepoIndexingJobType . INDEX ? 'index' : 'cleanup' ;
0 commit comments