Skip to content

Commit bd088ed

Browse files
committed
Speedup for initial synchronisation in case the forbidden folders are near the root path. Avoid invalid reparse point exceptions.
1 parent d3c62c9 commit bd088ed

File tree

2 files changed

+93
-32
lines changed

2 files changed

+93
-32
lines changed

Program.cs

Lines changed: 92 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -179,49 +179,46 @@ private static async Task MainTask()
179179
watch.Start();
180180

181181

182-
if (true)
183-
{
184-
var messageContext = new Context(
185-
eventObj: null,
186-
token: new CancellationToken()
187-
);
182+
var messageContext = new Context(
183+
eventObj: null,
184+
token: new CancellationToken()
185+
);
186+
188187

188+
await ConsoleWatch.AddMessage(ConsoleColor.White, "Doing initial synchronisation...", messageContext);
189+
ConsoleWatch.DoingInitialSync = true; //NB!
189190

190-
await ConsoleWatch.AddMessage(ConsoleColor.White, "Doing initial synchronisation...", messageContext);
191-
ConsoleWatch.DoingInitialSync = true; //NB!
192191

193192

194-
//1. Do initial synchronisation from sync to async folder //TODO: config for enabling and ordering of this operation
195-
foreach (var fileInfo in new DirectoryInfo(Global.SyncPath)
196-
.GetFiles("*." + Global.WatchedCodeExtension, SearchOption.AllDirectories))
193+
//1. Do initial synchronisation from sync to async folder //TODO: config for enabling and ordering of this operation
194+
foreach (var fileInfo in ProcessSubDirs(new DirectoryInfo(Global.SyncPath), "*." + Global.WatchedCodeExtension))
195+
{
197196
{
198-
{
199-
await ConsoleWatch.OnAddedAsync
200-
(
201-
new DummyFileSystemEvent(fileInfo),
202-
new CancellationToken()
203-
);
204-
}
197+
await ConsoleWatch.OnAddedAsync
198+
(
199+
new DummyFileSystemEvent(fileInfo),
200+
new CancellationToken()
201+
);
205202
}
203+
}
206204

207-
if (Global.Bidirectional)
205+
if (Global.Bidirectional)
206+
{
207+
//2. Do initial synchronisation from async to sync folder //TODO: config for enabling and ordering of this operation
208+
foreach (var fileInfo in ProcessSubDirs(new DirectoryInfo(Global.AsyncPath), "*." + Global.WatchedCodeExtension))
208209
{
209-
//2. Do initial synchronisation from async to sync folder //TODO: config for enabling and ordering of this operation
210-
foreach (var fileInfo in new DirectoryInfo(Global.AsyncPath)
211-
.GetFiles("*." + Global.WatchedCodeExtension, SearchOption.AllDirectories))
212-
{
213-
await ConsoleWatch.OnAddedAsync
214-
(
215-
new DummyFileSystemEvent(fileInfo),
216-
new CancellationToken()
217-
);
218-
}
210+
await ConsoleWatch.OnAddedAsync
211+
(
212+
new DummyFileSystemEvent(fileInfo),
213+
new CancellationToken()
214+
);
219215
}
216+
}
220217

221218

222-
ConsoleWatch.DoingInitialSync = false; //NB!
223-
await ConsoleWatch.AddMessage(ConsoleColor.White, "Done initial synchronisation...", messageContext);
224-
}
219+
220+
ConsoleWatch.DoingInitialSync = false; //NB!
221+
await ConsoleWatch.AddMessage(ConsoleColor.White, "Done initial synchronisation...", messageContext);
225222

226223

227224
//listen for the Ctrl+C
@@ -243,6 +240,67 @@ await ConsoleWatch.OnAddedAsync
243240
}
244241
}
245242

243+
private static IEnumerable<FileInfo> ProcessSubDirs(DirectoryInfo srcDirInfo, string searchPattern, int recursionLevel = 0)
244+
{
245+
#if false //this built-in functio will throw IOException in case some subfolder is an invalid reparse point
246+
return new DirectoryInfo(sourceDir)
247+
.GetFiles(searchPattern, SearchOption.AllDirectories);
248+
#else
249+
FileInfo[] fileInfos;
250+
try
251+
{
252+
fileInfos = srcDirInfo.GetFiles(searchPattern, SearchOption.TopDirectoryOnly);
253+
}
254+
catch (DirectoryNotFoundException)
255+
{
256+
//ignore exceptions due to long pathnames //TODO: find a way to handle them
257+
fileInfos = Array.Empty<FileInfo>();
258+
}
259+
260+
foreach (var fileInfo in fileInfos)
261+
{
262+
yield return fileInfo;
263+
}
264+
265+
266+
DirectoryInfo[] dirInfos;
267+
#pragma warning disable S2327 //Warning S2327 Combine this 'try' with the one starting on line XXX.
268+
try
269+
{
270+
dirInfos = srcDirInfo.GetDirectories("*", SearchOption.TopDirectoryOnly);
271+
}
272+
catch (DirectoryNotFoundException)
273+
{
274+
//ignore exceptions due to long pathnames //TODO: find a way to handle them
275+
dirInfos = Array.Empty<DirectoryInfo>();
276+
}
277+
#pragma warning restore S2327
278+
279+
foreach (var dirInfo in dirInfos)
280+
{
281+
//TODO: option to follow reparse points
282+
if ((dirInfo.Attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)
283+
continue;
284+
285+
286+
var nonFullNameInvariant = ConsoleWatch.GetNonFullName(dirInfo.FullName) + Path.PathSeparator;
287+
if (
288+
Global.IgnorePathsStartingWith.Any(x => nonFullNameInvariant.StartsWith(x))
289+
|| Global.IgnorePathsContaining.Any(x => nonFullNameInvariant.Contains(x))
290+
)
291+
{
292+
continue;
293+
}
294+
295+
296+
var subDirFileInfos = ProcessSubDirs(dirInfo, searchPattern, recursionLevel + 1);
297+
foreach (var subDirFileInfo in subDirFileInfos)
298+
{
299+
yield return subDirFileInfo;
300+
}
301+
} //foreach (var dirInfo in dirInfos)
302+
#endif
303+
} //private static IEnumerable<FileInfo> ProcessSubDirs(DirectoryInfo srcDirInfo, string searchPattern, bool forHistory, int recursionLevel = 0)
246304
private static void WriteException(Exception ex)
247305
{
248306
if (ex is AggregateException aggex)
@@ -445,7 +503,9 @@ public static DateTime GetBidirectionalConverterSaveDate(string fullName)
445503
public static bool NeedsUpdate(string fullName)
446504
{
447505
if (DoingInitialSync)
506+
{
448507
return true;
508+
}
449509

450510
var converterSaveDate = GetBidirectionalConverterSaveDate(fullName);
451511
var fileTime = GetFileTime(fullName);

appsettings.example.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
"ExcludedExtensions": [
1515
"*~",
16+
"bak",
1617
"tmp"
1718
],
1819

0 commit comments

Comments
 (0)