Deliver an event enum with the queue overflow as its own case
The stream's element is now the enum InotifyEvent, and the struct that describes a change to a watched item is FileSystemEvent. A queue overflow was an event with descriptor -1 and an empty path that every consumer had to know about; as a case, the compiler makes them handle it. The enum is also where failed watches of a growing tree will be reported, since no call site can catch them.
This commit is contained in:
@@ -50,7 +50,7 @@ struct InotifyLimitTests {
|
||||
var received = 0
|
||||
for await event in await watcher.events {
|
||||
received += 1
|
||||
if event.mask.contains(.queueOverflow) { return (event, received) }
|
||||
if case .queueOverflow = event { return (event, received) }
|
||||
}
|
||||
return (nil, received)
|
||||
}
|
||||
@@ -65,9 +65,7 @@ struct InotifyLimitTests {
|
||||
overflowTask.cancel()
|
||||
let (overflow, received) = await overflowTask.value
|
||||
|
||||
#expect(overflow != nil, "Expected a queue overflow event after \(index) file creations and \(received) received events")
|
||||
#expect(overflow?.watchDescriptor == -1)
|
||||
#expect(overflow?.path == "")
|
||||
#expect(overflow == .queueOverflow, "Expected a queue overflow event after \(index) file creations and \(received) received events")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ enum RecursivKind {
|
||||
case withAutomaticSubtreeWatching
|
||||
}
|
||||
|
||||
/// The file system events an instance delivers around `trigger`.
|
||||
func getEventsForTrigger(
|
||||
in dir: String,
|
||||
mask: InotifyEventMask,
|
||||
@@ -13,6 +14,27 @@ func getEventsForTrigger(
|
||||
exclude: [String] = [],
|
||||
excludePatterns: [String] = [],
|
||||
trigger: @escaping (String) async throws -> Void,
|
||||
) async throws -> [FileSystemEvent] {
|
||||
let events = try await getInotifyEventsForTrigger(
|
||||
in: dir,
|
||||
mask: mask,
|
||||
recursive: recursive,
|
||||
exclude: exclude,
|
||||
excludePatterns: excludePatterns,
|
||||
trigger: trigger
|
||||
)
|
||||
return events.compactMap(\.fileSystemEvent)
|
||||
}
|
||||
|
||||
/// Everything an instance delivers around `trigger`, including the
|
||||
/// events that are not about a file system item.
|
||||
func getInotifyEventsForTrigger(
|
||||
in dir: String,
|
||||
mask: InotifyEventMask,
|
||||
recursive: RecursivKind = .nonrecursive,
|
||||
exclude: [String] = [],
|
||||
excludePatterns: [String] = [],
|
||||
trigger: @escaping (String) async throws -> Void,
|
||||
) async throws -> [InotifyEvent] {
|
||||
let watcher = try Inotify()
|
||||
await watcher.exclude(names: exclude)
|
||||
@@ -41,3 +63,10 @@ func getEventsForTrigger(
|
||||
eventTask.cancel()
|
||||
return await eventTask.value
|
||||
}
|
||||
|
||||
extension InotifyEvent {
|
||||
var fileSystemEvent: FileSystemEvent? {
|
||||
if case .fileSystem(let event) = self { return event }
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user