FileSystemWatcher on macOS raises no Error when FSEvents drops events: the flags arrive on the watched folder's own path, which is skipped first
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 76/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- csharp, macos
- Lĩnh vực
- backend, operating-systems
Hướng nghiên cứu
Đọc src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.OSX.cs, đặc biệt là ProcessEvents ở phần bỏ qua đường dẫn gốc và lời gọi ShouldRescanOccur. Tái hiện bằng ứng dụng console xóa hàng loạt được cung cấp trên macOS và kiểm tra xem các FSEvents bị mất có kích hoạt sự kiện Error của watcher hay không. Công việc được xem là hoàn tất khi sự kiện đường dẫn gốc có các cờ báo sự kiện bị mất được báo cáo là lỗi và có bài kiểm thử hồi quy bao quát thứ tự xử lý đó.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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.
- Ngôn ngữ chính
- C#
- Star
- 18.4k
- Fork
- 5.8k
- Merge trung bình
- 2 ngày 16 giờ
- Pull request đã merge (30 ngày)
- 621
Chuẩn bị môi trường
Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của dotnet/runtime
-
[wasi] .NET 10: WasmEnableSIMD with AOT fails because WasiApp.targets has -msimd128 commented outĐang mởarea-Build-mono untriaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
area-System.ComponentModel untriaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
dotnet/runtime#136608 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
area-System.IO bug untriaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
dotnet/runtime#136599 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[mono] Native memory leak on the first invoke of every open-instance delegate to a virtual methodĐang mởarea-VM-meta-mono untriaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
dotnet/runtime#136284 · 6 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Several MemoryExtensions.LastIndexOfAnyExcept overloads incorrectly document "first occurrence"Có thể làm lại được @ehsan-raoufi đã nhận 7 ngày trước và không có pull request nào đang mở. Đang mởarea-System.Memory untriaged
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 83/100
dotnet/runtime#136282 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của dotnet/runtime
Issue tương tự
-
请让 FPS 叠加层的字号大小可单独设置Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Maintainer thường phản hồi trong vòng 1 ngày
-
امکان انتخاب متن پیام هرزنامهĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
MahdiyarGHD/GheychiApp#39 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
bug effort:S P3
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
nightscout/nocturne#3136 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100