@@ -108,6 +108,11 @@ type Session struct {
108
108
// after file watch changes and ATA updates.
109
109
diagnosticsRefreshCancel context.CancelFunc
110
110
diagnosticsRefreshMu sync.Mutex
111
+
112
+ // watches tracks the current watch globs and how many individual WatchedFiles
113
+ // are using each glob.
114
+ watches map [fileSystemWatcherKey ]int
115
+ watchesMu sync.Mutex
111
116
}
112
117
113
118
func NewSession (init * SessionInit ) * Session {
@@ -149,6 +154,7 @@ func NewSession(init *SessionInit) *Session {
149
154
toPath ,
150
155
),
151
156
pendingATAChanges : make (map [tspath.Path ]* ATAStateChange ),
157
+ watches : make (map [fileSystemWatcherKey ]int ),
152
158
}
153
159
154
160
if init .Options .TypingsLocation != "" && init .NpmExecutor != nil {
@@ -410,33 +416,57 @@ func (s *Session) WaitForBackgroundTasks() {
410
416
s .backgroundQueue .Wait ()
411
417
}
412
418
413
- func updateWatch [T any ](ctx context.Context , client Client , logger logging.Logger , oldWatcher , newWatcher * WatchedFiles [T ]) []error {
419
+ func updateWatch [T any ](ctx context.Context , session * Session , logger logging.Logger , oldWatcher , newWatcher * WatchedFiles [T ]) []error {
414
420
var errors []error
421
+ session .watchesMu .Lock ()
422
+ defer session .watchesMu .Unlock ()
415
423
if newWatcher != nil {
416
424
if id , watchers := newWatcher .Watchers (); len (watchers ) > 0 {
417
- if err := client .WatchFiles (ctx , id , watchers ); err != nil {
418
- errors = append (errors , err )
419
- }
420
- if logger != nil {
421
- if oldWatcher == nil {
422
- logger .Log (fmt .Sprintf ("Added new watch: %s" , id ))
423
- } else {
424
- logger .Log (fmt .Sprintf ("Updated watch: %s" , id ))
425
+ var newWatchers []* lsproto.FileSystemWatcher
426
+ for _ , watcher := range watchers {
427
+ key := toFileSystemWatcherKey (watcher )
428
+ count := session .watches [key ]
429
+ session .watches [key ] = count + 1
430
+ if count == 0 {
431
+ newWatchers = append (newWatchers , watcher )
425
432
}
426
- for _ , watcher := range watchers {
427
- logger .Log ("\t " + * watcher .GlobPattern .Pattern )
433
+ }
434
+ if len (newWatchers ) > 0 {
435
+ if err := session .client .WatchFiles (ctx , id , newWatchers ); err != nil {
436
+ errors = append (errors , err )
437
+ } else if logger != nil {
438
+ if oldWatcher == nil {
439
+ logger .Log (fmt .Sprintf ("Added new watch: %s" , id ))
440
+ } else {
441
+ logger .Log (fmt .Sprintf ("Updated watch: %s" , id ))
442
+ }
443
+ for _ , watcher := range watchers {
444
+ logger .Log ("\t " + * watcher .GlobPattern .Pattern )
445
+ }
446
+ logger .Log ("" )
428
447
}
429
- logger .Log ("" )
430
448
}
431
449
}
432
450
}
433
451
if oldWatcher != nil {
434
452
if id , watchers := oldWatcher .Watchers (); len (watchers ) > 0 {
435
- if err := client .UnwatchFiles (ctx , id ); err != nil {
436
- errors = append (errors , err )
453
+ var removedWatchers []WatcherID
454
+ for _ , watcher := range watchers {
455
+ key := toFileSystemWatcherKey (watcher )
456
+ count := session .watches [key ]
457
+ if count <= 1 {
458
+ delete (session .watches , key )
459
+ removedWatchers = append (removedWatchers , id )
460
+ } else {
461
+ session .watches [key ] = count - 1
462
+ }
437
463
}
438
- if logger != nil && newWatcher == nil {
439
- logger .Log (fmt .Sprintf ("Removed watch: %s" , id ))
464
+ for _ , id := range removedWatchers {
465
+ if err := session .client .UnwatchFiles (ctx , id ); err != nil {
466
+ errors = append (errors , err )
467
+ } else if logger != nil && newWatcher == nil {
468
+ logger .Log (fmt .Sprintf ("Removed watch: %s" , id ))
469
+ }
440
470
}
441
471
}
442
472
}
@@ -453,43 +483,38 @@ func (s *Session) updateWatches(oldSnapshot *Snapshot, newSnapshot *Snapshot) er
453
483
return a .rootFilesWatch .ID () == b .rootFilesWatch .ID ()
454
484
},
455
485
func (_ tspath.Path , addedEntry * configFileEntry ) {
456
- errors = append (errors , updateWatch (ctx , s . client , s .logger , nil , addedEntry .rootFilesWatch )... )
486
+ errors = append (errors , updateWatch (ctx , s , s .logger , nil , addedEntry .rootFilesWatch )... )
457
487
},
458
488
func (_ tspath.Path , removedEntry * configFileEntry ) {
459
- errors = append (errors , updateWatch (ctx , s . client , s .logger , removedEntry .rootFilesWatch , nil )... )
489
+ errors = append (errors , updateWatch (ctx , s , s .logger , removedEntry .rootFilesWatch , nil )... )
460
490
},
461
491
func (_ tspath.Path , oldEntry , newEntry * configFileEntry ) {
462
- errors = append (errors , updateWatch (ctx , s . client , s .logger , oldEntry .rootFilesWatch , newEntry .rootFilesWatch )... )
492
+ errors = append (errors , updateWatch (ctx , s , s .logger , oldEntry .rootFilesWatch , newEntry .rootFilesWatch )... )
463
493
},
464
494
)
465
495
466
496
collections .DiffOrderedMaps (
467
497
oldSnapshot .ProjectCollection .ProjectsByPath (),
468
498
newSnapshot .ProjectCollection .ProjectsByPath (),
469
499
func (_ tspath.Path , addedProject * Project ) {
470
- errors = append (errors , updateWatch (ctx , s .client , s .logger , nil , addedProject .affectingLocationsWatch )... )
471
- errors = append (errors , updateWatch (ctx , s .client , s .logger , nil , addedProject .failedLookupsWatch )... )
472
- errors = append (errors , updateWatch (ctx , s .client , s .logger , nil , addedProject .typingsFilesWatch )... )
473
- errors = append (errors , updateWatch (ctx , s .client , s .logger , nil , addedProject .typingsDirectoryWatch )... )
500
+ errors = append (errors , updateWatch (ctx , s , s .logger , nil , addedProject .affectingLocationsWatch )... )
501
+ errors = append (errors , updateWatch (ctx , s , s .logger , nil , addedProject .failedLookupsWatch )... )
502
+ errors = append (errors , updateWatch (ctx , s , s .logger , nil , addedProject .typingsWatch )... )
474
503
},
475
504
func (_ tspath.Path , removedProject * Project ) {
476
- errors = append (errors , updateWatch (ctx , s .client , s .logger , removedProject .affectingLocationsWatch , nil )... )
477
- errors = append (errors , updateWatch (ctx , s .client , s .logger , removedProject .failedLookupsWatch , nil )... )
478
- errors = append (errors , updateWatch (ctx , s .client , s .logger , removedProject .typingsFilesWatch , nil )... )
479
- errors = append (errors , updateWatch (ctx , s .client , s .logger , removedProject .typingsDirectoryWatch , nil )... )
505
+ errors = append (errors , updateWatch (ctx , s , s .logger , removedProject .affectingLocationsWatch , nil )... )
506
+ errors = append (errors , updateWatch (ctx , s , s .logger , removedProject .failedLookupsWatch , nil )... )
507
+ errors = append (errors , updateWatch (ctx , s , s .logger , removedProject .typingsWatch , nil )... )
480
508
},
481
509
func (_ tspath.Path , oldProject , newProject * Project ) {
482
510
if oldProject .affectingLocationsWatch .ID () != newProject .affectingLocationsWatch .ID () {
483
- errors = append (errors , updateWatch (ctx , s . client , s .logger , oldProject .affectingLocationsWatch , newProject .affectingLocationsWatch )... )
511
+ errors = append (errors , updateWatch (ctx , s , s .logger , oldProject .affectingLocationsWatch , newProject .affectingLocationsWatch )... )
484
512
}
485
513
if oldProject .failedLookupsWatch .ID () != newProject .failedLookupsWatch .ID () {
486
- errors = append (errors , updateWatch (ctx , s .client , s .logger , oldProject .failedLookupsWatch , newProject .failedLookupsWatch )... )
487
- }
488
- if oldProject .typingsFilesWatch .ID () != newProject .typingsFilesWatch .ID () {
489
- errors = append (errors , updateWatch (ctx , s .client , s .logger , oldProject .typingsFilesWatch , newProject .typingsFilesWatch )... )
514
+ errors = append (errors , updateWatch (ctx , s , s .logger , oldProject .failedLookupsWatch , newProject .failedLookupsWatch )... )
490
515
}
491
- if oldProject .typingsDirectoryWatch .ID () != newProject .typingsDirectoryWatch .ID () {
492
- errors = append (errors , updateWatch (ctx , s . client , s .logger , oldProject .typingsDirectoryWatch , newProject .typingsDirectoryWatch )... )
516
+ if oldProject .typingsWatch .ID () != newProject .typingsWatch .ID () {
517
+ errors = append (errors , updateWatch (ctx , s , s .logger , oldProject .typingsWatch , newProject .typingsWatch )... )
493
518
}
494
519
},
495
520
)
0 commit comments