From a0607f9dbd86b860ad090fdd919340b2e2f55b99 Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Mon, 29 Jul 2024 01:29:40 -0700 Subject: [PATCH] Fixed an issue where disk file handles for memory cached data were held open indefinitely --- .../Disk Persistence/Datastore/DatastorePage.swift | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Sources/CodableDatastore/Persistence/Disk Persistence/Datastore/DatastorePage.swift b/Sources/CodableDatastore/Persistence/Disk Persistence/Datastore/DatastorePage.swift index 5bda3c7..22ca051 100644 --- a/Sources/CodableDatastore/Persistence/Disk Persistence/Datastore/DatastorePage.swift +++ b/Sources/CodableDatastore/Persistence/Disk Persistence/Datastore/DatastorePage.swift @@ -168,7 +168,7 @@ actor MultiplexedAsyncSequence: AsyncSequence wh typealias Element = Base.Element private var cachedEntries: [Task] = [] - private var baseIterator: Base.AsyncIterator + private var baseIterator: Base.AsyncIterator? struct AsyncIterator: AsyncIteratorProtocol & Sendable { let base: MultiplexedAsyncSequence @@ -206,10 +206,11 @@ actor MultiplexedAsyncSequence: AsyncSequence wh } } - nonisolated func nextBase(iterator: Base.AsyncIterator) async throws -> (Element?, Base.AsyncIterator) { + /// Return the next base iterator to use along with the current entry, or nil if we've reached the end, so we don't retail the open file handles in our memory caches. + nonisolated func nextBase(iterator: Base.AsyncIterator?) async throws -> (Element?, Base.AsyncIterator?) { var iteratorCopy = iterator - let nextEntry = try await iteratorCopy.next() - return (nextEntry, iteratorCopy) + let nextEntry = try await iteratorCopy?.next() + return (nextEntry, nextEntry.flatMap { _ in iteratorCopy }) } nonisolated func makeAsyncIterator() -> AsyncIterator {