@@ -6,6 +6,7 @@ import { DEFAULT_REPO_STATE, ExtensionState } from './extensionState';
66import { Logger } from './logger' ;
77import { GitRepoSet , GitRepoState } from './types' ;
88import { evalPromises , getPathFromUri , pathWithTrailingSlash , realpath } from './utils' ;
9+ import { BufferedQueue } from './utils/bufferedQueue' ;
910import { Disposable , toDisposable } from './utils/disposable' ;
1011import { Event , EventEmitter } from './utils/event' ;
1112
@@ -22,18 +23,16 @@ export class RepoManager extends Disposable {
2223 private readonly dataSource : DataSource ;
2324 private readonly extensionState : ExtensionState ;
2425 private readonly logger : Logger ;
26+
2527 private repos : GitRepoSet ;
2628 private ignoredRepos : string [ ] ;
2729 private maxDepthOfRepoSearch : number ;
30+
2831 private readonly folderWatchers : { [ workspace : string ] : vscode . FileSystemWatcher } = { } ;
2932 private readonly repoEventEmitter : EventEmitter < RepoChangeEvent > ;
3033
31- private readonly createEventQueue : string [ ] = [ ] ;
32- private readonly changeEventQueue : string [ ] = [ ] ;
33- private processCreateEventsTimeout : NodeJS . Timer | null = null ;
34- private processChangeEventsTimeout : NodeJS . Timer | null = null ;
35- private processingCreateEvents : boolean = false ;
36- private processingChangeEvents : boolean = false ;
34+ private readonly onWatcherCreateQueue : BufferedQueue < string > ;
35+ private readonly onWatcherChangeQueue : BufferedQueue < string > ;
3736
3837 /**
3938 * Creates the Git Graph Repository Manager, and runs startup tasks.
@@ -49,7 +48,12 @@ export class RepoManager extends Disposable {
4948 this . repos = extensionState . getRepos ( ) ;
5049 this . ignoredRepos = extensionState . getIgnoredRepos ( ) ;
5150 this . maxDepthOfRepoSearch = getConfig ( ) . maxDepthOfRepoSearch ;
51+
5252 this . repoEventEmitter = new EventEmitter < RepoChangeEvent > ( ) ;
53+
54+ this . onWatcherCreateQueue = new BufferedQueue < string > ( this . processOnWatcherCreateEvent . bind ( this ) , this . sendRepos . bind ( this ) ) ;
55+ this . onWatcherChangeQueue = new BufferedQueue < string > ( this . processOnWatcherChangeEvent . bind ( this ) , this . sendRepos . bind ( this ) ) ;
56+
5357 this . startupTasks ( ) ;
5458
5559 this . registerDisposables (
@@ -83,6 +87,12 @@ export class RepoManager extends Disposable {
8387 // Dispose the Repository Event Emitter when disposed
8488 this . repoEventEmitter ,
8589
90+ // Dispose the onWatcherCreateQueue
91+ this . onWatcherCreateQueue ,
92+
93+ // Dispose the onWatcherChangeQueue
94+ this . onWatcherChangeQueue ,
95+
8696 // Stop watching folders when disposed
8797 toDisposable ( ( ) => {
8898 const folders = Object . keys ( this . folderWatchers ) ;
@@ -483,9 +493,9 @@ export class RepoManager extends Disposable {
483493 */
484494 private startWatchingFolder ( path : string ) {
485495 let watcher = vscode . workspace . createFileSystemWatcher ( path + '/**' ) ;
486- watcher . onDidCreate ( uri => this . onWatcherCreate ( uri ) ) ;
487- watcher . onDidChange ( uri => this . onWatcherChange ( uri ) ) ;
488- watcher . onDidDelete ( uri => this . onWatcherDelete ( uri ) ) ;
496+ watcher . onDidCreate ( ( uri ) => this . onWatcherCreate ( uri ) ) ;
497+ watcher . onDidChange ( ( uri ) => this . onWatcherChange ( uri ) ) ;
498+ watcher . onDidDelete ( ( uri ) => this . onWatcherDelete ( uri ) ) ;
489499 this . folderWatchers [ path ] = watcher ;
490500 }
491501
@@ -499,53 +509,29 @@ export class RepoManager extends Disposable {
499509 }
500510
501511 /**
502- * Process a file system creation event.
512+ * Handle a file system creation event.
503513 * @param uri The URI of the creation event.
504514 */
505515 private onWatcherCreate ( uri : vscode . Uri ) {
506516 let path = getPathFromUri ( uri ) ;
507517 if ( path . indexOf ( '/.git/' ) > - 1 ) return ;
508518 if ( path . endsWith ( '/.git' ) ) path = path . slice ( 0 , - 5 ) ;
509- if ( this . createEventQueue . indexOf ( path ) > - 1 ) return ;
510-
511- this . createEventQueue . push ( path ) ;
512-
513- if ( ! this . processingCreateEvents ) {
514- if ( this . processCreateEventsTimeout !== null ) {
515- clearTimeout ( this . processCreateEventsTimeout ) ;
516- }
517- this . processCreateEventsTimeout = setTimeout ( ( ) => {
518- this . processCreateEventsTimeout = null ;
519- this . processCreateEvents ( ) ;
520- } , 1000 ) ;
521- }
519+ this . onWatcherCreateQueue . enqueue ( path ) ;
522520 }
523521
524522 /**
525- * Process a file system change event.
523+ * Handle a file system change event.
526524 * @param uri The URI of the change event.
527525 */
528526 private onWatcherChange ( uri : vscode . Uri ) {
529527 let path = getPathFromUri ( uri ) ;
530528 if ( path . indexOf ( '/.git/' ) > - 1 ) return ;
531529 if ( path . endsWith ( '/.git' ) ) path = path . slice ( 0 , - 5 ) ;
532- if ( this . changeEventQueue . indexOf ( path ) > - 1 ) return ;
533-
534- this . changeEventQueue . push ( path ) ;
535-
536- if ( ! this . processingChangeEvents ) {
537- if ( this . processChangeEventsTimeout !== null ) {
538- clearTimeout ( this . processChangeEventsTimeout ) ;
539- }
540- this . processChangeEventsTimeout = setTimeout ( ( ) => {
541- this . processChangeEventsTimeout = null ;
542- this . processChangeEvents ( ) ;
543- } , 1000 ) ;
544- }
530+ this . onWatcherChangeQueue . enqueue ( path ) ;
545531 }
546532
547533 /**
548- * Process a file system deletion event.
534+ * Handle a file system deletion event.
549535 * @param uri The URI of the deletion event.
550536 */
551537 private onWatcherDelete ( uri : vscode . Uri ) {
@@ -556,33 +542,31 @@ export class RepoManager extends Disposable {
556542 }
557543
558544 /**
559- * Process the queue of file system creation events.
545+ * Process a file system creation event.
546+ * @param path The path of the file that was created.
547+ * @returns TRUE => Change was made. FALSE => No change was made.
560548 */
561- private async processCreateEvents ( ) {
562- this . processingCreateEvents = true ;
563- let path , changes = false ;
564- while ( path = this . createEventQueue . shift ( ) ) {
565- if ( await isDirectory ( path ) ) {
566- if ( await this . searchDirectoryForRepos ( path , this . maxDepthOfRepoSearch ) ) changes = true ;
549+ private async processOnWatcherCreateEvent ( path : string ) {
550+ if ( await isDirectory ( path ) ) {
551+ if ( await this . searchDirectoryForRepos ( path , this . maxDepthOfRepoSearch ) ) {
552+ return true ;
567553 }
568554 }
569- this . processingCreateEvents = false ;
570- if ( changes ) this . sendRepos ( ) ;
555+ return false ;
571556 }
572557
573558 /**
574- * Process the queue of file system change events
559+ * Process a file system change event.
560+ * @param path The path of the file that was changed.
561+ * @returns TRUE => Change was made. FALSE => No change was made.
575562 */
576- private async processChangeEvents ( ) {
577- this . processingChangeEvents = true ;
578- let path , changes = false ;
579- while ( path = this . changeEventQueue . shift ( ) ) {
580- if ( ! await doesPathExist ( path ) ) {
581- if ( this . removeReposWithinFolder ( path ) ) changes = true ;
563+ private async processOnWatcherChangeEvent ( path : string ) {
564+ if ( ! await doesPathExist ( path ) ) {
565+ if ( this . removeReposWithinFolder ( path ) ) {
566+ return true ;
582567 }
583568 }
584- this . processingChangeEvents = false ;
585- if ( changes ) this . sendRepos ( ) ;
569+ return false ;
586570 }
587571}
588572
0 commit comments