Show folder names immediately and refresh stale index sizes without walking the whole drive.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -20,6 +20,8 @@ public sealed class SourceManager
|
||||
private long _refreshCacheTimestamp;
|
||||
private static readonly TimeSpan RefreshCacheTtl = TimeSpan.FromSeconds(2);
|
||||
|
||||
public event EventHandler<Source>? PresenceChanged;
|
||||
|
||||
public SourceManager(
|
||||
IIndexStore store,
|
||||
IVolumeService volumes,
|
||||
@@ -176,6 +178,7 @@ public sealed class SourceManager
|
||||
&& (source.Kind.IsNetwork() || PathRules.IsUnc(source.LastRootPath))
|
||||
&& _volumes.IsPathReachable(source.LastRootPath))
|
||||
{
|
||||
await BringOnlineAsync(source, cancellationToken).ConfigureAwait(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -282,6 +285,77 @@ public sealed class SourceManager
|
||||
return source;
|
||||
}
|
||||
|
||||
public async Task<Source?> MarkReachableAsync(string path, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path) || LocationRoots.IsVirtual(path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!_store.CanWrite)
|
||||
{
|
||||
if (_remote is null)
|
||||
{
|
||||
return await FindByPathAsync(path, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var current = await FindByPathAsync(path, cancellationToken).ConfigureAwait(false);
|
||||
if (current is { Status: SourceStatus.Online or SourceStatus.Stale or SourceStatus.Scanning })
|
||||
{
|
||||
return current;
|
||||
}
|
||||
|
||||
var updated = await _remote.MarkReachableAsync(path, cancellationToken).ConfigureAwait(false);
|
||||
InvalidateRefreshCache();
|
||||
var source = updated ?? await FindByPathAsync(path, cancellationToken).ConfigureAwait(false);
|
||||
if (source is not null)
|
||||
{
|
||||
RaisePresence(source);
|
||||
}
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
var found = await FindByPathAsync(path, cancellationToken).ConfigureAwait(false);
|
||||
if (found is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
await BringOnlineAsync(found, cancellationToken).ConfigureAwait(false);
|
||||
return found;
|
||||
}
|
||||
|
||||
public async Task ConfirmAccessedAsync(string path, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path) || LocationRoots.IsVirtual(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var source = await FindByPathAsync(path, cancellationToken).ConfigureAwait(false);
|
||||
if (source is null || source.Status != SourceStatus.Offline)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_volumes.IsPathReachable(path))
|
||||
{
|
||||
await MarkReachableAsync(path, cancellationToken).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
for (var attempt = 0; attempt < 4; attempt++)
|
||||
{
|
||||
await Task.Delay(500, cancellationToken).ConfigureAwait(false);
|
||||
if (_volumes.IsPathReachable(path))
|
||||
{
|
||||
await MarkReachableAsync(path, cancellationToken).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPresentInWindows(Source source)
|
||||
{
|
||||
var online = _volumes.EnumerateOnlineVolumes();
|
||||
@@ -528,6 +602,42 @@ public sealed class SourceManager
|
||||
public Task<Source?> GetAsync(long id, CancellationToken cancellationToken = default)
|
||||
=> _store.Sources.GetAsync(id, cancellationToken);
|
||||
|
||||
private async Task BringOnlineAsync(Source source, CancellationToken cancellationToken)
|
||||
{
|
||||
if (source.Status == SourceStatus.Scanning
|
||||
&& await _store.ScanJobs.HasActiveAsync(source.Id, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (source.Status is SourceStatus.Online or SourceStatus.Stale)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var wasOffline = source.Status == SourceStatus.Offline;
|
||||
source.Status = SourceStatus.Online;
|
||||
source.LastSeenUtc = _clock.UtcNow;
|
||||
source.LastError = null;
|
||||
await TryIndexWrite(
|
||||
() => _store.Sources.UpsertAsync(source, cancellationToken),
|
||||
"mark source online",
|
||||
source.Id).ConfigureAwait(false);
|
||||
if (source.IsIndexed && wasOffline)
|
||||
{
|
||||
await TryIndexWrite(
|
||||
() => _store.Entries.MarkSourceOnlinePresentAsync(source.Id, cancellationToken),
|
||||
"mark online",
|
||||
source.Id).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
InvalidateRefreshCache();
|
||||
RaisePresence(source);
|
||||
}
|
||||
|
||||
private void RaisePresence(Source source)
|
||||
=> PresenceChanged?.Invoke(this, source);
|
||||
|
||||
private async Task<SourceStatus> ResolveReachableStatusAsync(Source source, CancellationToken cancellationToken)
|
||||
{
|
||||
if (source.Status == SourceStatus.Scanning
|
||||
|
||||
Reference in New Issue
Block a user