FileSystemWatcher on macOS raises no Error when FSEvents drops events: the flags arrive on the watched folder's own path, which is skipped first
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 76/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- csharp, macos
- Área
- backend, operating-systems
Línea de trabajo
Lee src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.OSX.cs, especialmente ProcessEvents en torno al salto de la ruta raíz y la llamada a ShouldRescanOccur. Reproduce el problema con la aplicación de consola proporcionada para borrar en ráfaga en macOS y comprueba si los FSEvents descartados activan el evento Error del watcher. Se considera terminado cuando el evento de la ruta raíz que lleva los flags de eventos descartados se notifica como un error y una prueba de regresión cubre ese orden.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Description
On macOS, when more changes arrive at once than FSEvents queues, FSEvents drops events and says so with one event flagged kFSEventStreamEventFlagMustScanSubDirs | kFSEventStreamEventFlagUserDropped (0x3). That event's path is the watched folder itself.
ProcessEvents in FileSystemWatcher.OSX.cs skips every event on the watched folder's own path ("Match Windows and don't notify us about changes to the Root folder") before it calls ShouldRescanOccur. So the dropped-events flags never reach the Error event. The watcher loses changes silently, and its consumer can't tell it should rescan.
Reproduction Steps
A net10.0/net11.0 console app:
using System.Collections.Concurrent;
int count = args.Length > 0 ? int.Parse(args[0]) : 1000;
string folder = Directory.CreateTempSubdirectory("fsw-burst-").FullName;
for (int i = 0; i < count; i++)
{
File.WriteAllText(Path.Combine(folder, $"F{i}.txt"), "x");
}
Thread.Sleep(1000);
ConcurrentDictionary<string, bool> deleted = new();
int errors = 0;
using FileSystemWatcher watcher = new(folder);
watcher.Deleted += (_, e) => deleted[e.FullPath] = true;
watcher.Error += (_, e) => { Interlocked.Increment(ref errors); Console.WriteLine($"Error: {e.GetException().Message}"); };
watcher.EnableRaisingEvents = true;
Thread.Sleep(1000);
Parallel.For(0, count, i => File.Delete(Path.Combine(folder, $"F{i}.txt")));
Thread.Sleep(5000);
Console.WriteLine($"{Environment.Version}: {count} files deleted, {deleted.Count} Deleted events, {errors} Error events");
Directory.Delete(folder, true);
Output on macOS 27.0.1, Apple Silicon, three runs on each runtime:
10.0.14: 1000 files deleted, 467 Deleted events, 0 Error events
10.0.14: 1000 files deleted, 544 Deleted events, 0 Error events
10.0.14: 1000 files deleted, 488 Deleted events, 0 Error events
11.0.0: 1000 files deleted, 466 Deleted events, 0 Error events
11.0.0: 1000 files deleted, 722 Deleted events, 0 Error events
11.0.0: 1000 files deleted, 1000 Deleted events, 0 Error events
A raw FSEvents stream, created with the flags the watcher uses (FileEvents, NoDefer, WatchRoot; latency 0) and watching the same burst, got 460 events: 459 file removals and one event on the watched folder's own path with flags 0x3. The same happens with IncludeSubdirectories = true and the files in a subfolder: the flagged event is still on the watched folder's path.
Expected behavior
Either a Deleted event for every file, or an Error event saying events were lost.
Actual behavior
About half the deletions are reported, with no Error event.
Regression?
Not known.
Known Workarounds
Treat a burst of changes as possibly lossy, and list again the folders it touched.
Configuration
macOS 27.0.1 (Apple Silicon), .NET 10.0.14 and 11.0.0-rc.3.26522.148.
Other information
Calling ShouldRescanOccur before the root-path skip would fix it. #130637 changes the exception this path raises to InternalBufferOverflowException. Its test reaches the path through a mount in a subfolder, so it doesn't hit this ordering.
- Lenguaje dominante
- C#
- Estrellas
- 18.4k
- Forks
- 5.8k
- Merge medio
- 2 d 16 h
- PR fusionados (30 d)
- 621
Preparar el entorno
Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de dotnet/runtime
-
[wasi] .NET 10: WasmEnableSIMD with AOT fails because WasiApp.targets has -msimd128 commented outAbiertoarea-Build-mono untriaged
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
area-System.ComponentModel untriaged
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
dotnet/runtime#136608 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
area-System.IO bug untriaged
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
dotnet/runtime#136599 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
[mono] Native memory leak on the first invoke of every open-instance delegate to a virtual methodAbiertoarea-VM-meta-mono untriaged
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
dotnet/runtime#136284 · 6 reacciones ·
Los mantenedores suelen responder en 1 día
-
Several MemoryExtensions.LastIndexOfAnyExcept overloads incorrectly document "first occurrence"Posiblemente ocupada @ehsan-raoufi la tomó hace 6 días. Abiertoarea-System.Memory untriaged
Dificultad 1/5 Menos de una hora Aptitud para principiantes 83/100
dotnet/runtime#136282 · 1 comentario ·
Los mantenedores suelen responder en 1 día
Todos los issues de dotnet/runtime
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 67/100
Los mantenedores suelen responder en 1 día
-
Исправить опечатки в протоколеAbierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 76/100
GameShowLDA/AskMkiM#1075 ·
Los mantenedores suelen responder en 1 día
-
kind/bug triage/untriaged
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
unoplatform/uno.resizetizer#414 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
Los mantenedores suelen responder en 1 día