Skip to content

Commit

Permalink
Fix nested transactions with async bodies (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcoarment committed Feb 10, 2024
1 parent 9b3bf0f commit ba13453
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
5 changes: 5 additions & 0 deletions Sources/Blackbird/BlackbirdDatabase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -591,8 +591,13 @@ extension Blackbird {
}
}

private let asyncTransactionSemaphore = Blackbird.Semaphore(value: 1)

// Exactly like the function below, but accepts an async action
public func cancellableTransaction<R: Sendable>(_ action: (@Sendable (_ core: isolated Blackbird.Database.Core) async throws -> R) ) async throws -> Blackbird.TransactionResult<R> {
await asyncTransactionSemaphore.wait()
defer { asyncTransactionSemaphore.signal() }

if isClosed { throw Error.databaseIsClosed }
let transactionID = nextTransactionID
nextTransactionID += 1
Expand Down
21 changes: 20 additions & 1 deletion Tests/BlackbirdTests/BlackbirdTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1030,7 +1030,26 @@ final class BlackbirdTestTests: XCTestCase, @unchecked Sendable {
XCTAssert(all[2].id == 3)
XCTAssert(all[2].a == "a2")
XCTAssert(all[2].b == 201)

}

// To test bug #25: https://github.com/marcoarment/Blackbird/issues/25
func testConcurrentTransactions() async throws {
let db = try Blackbird.Database(path: sqliteFilename)
let semaphore = Blackbird.Semaphore(value: 0)

let numTasks = 1000

for i in 0..<numTasks {
Task {
try! await db.transaction { core in
try? await Task.sleep(nanoseconds: UInt64(arc4random_uniform(10_000_000)))
try! TestModel(id: Int64(i), title: TestData.randomTitle, url: TestData.randomURL).writeIsolated(to: db, core: core)
}
semaphore.signal()
}
}

for _ in 0..<numTasks { await semaphore.wait() }
}

func testCache() async throws {
Expand Down

0 comments on commit ba13453

Please sign in to comment.