Closed scottandrew closed 5 years ago
Hello @scottandrew, and thanks for trying GRDBCombine!
The write publisher tests pass, so something is different in your setup and we need to find out what.
Would you please perform a few checks?
Sorry my fault. This is Xcode 11 beta 6 and the latest GRDBCombine. I am seeing this on a MacOS 10.15 beta 6 In a small command line app. The only event handleRequests get is receiveRequest. The apps complete code is below. The cancellable is held on too since we are just in a while loop below.
struct League: Codable, FetchableRecord, PersistableRecord {
enum CodingKeys: String, CodingKey {
case id
case name
case alias
}
let id: String
let name: String
let alias: String
}
let cancellable = dbPool.writePublisher(updates: { (db) -> Int in
let league = League(id: "123", name: "foo", alias: "foo")
try league.insert(db)
return try League.fetchCount(db)
})
.sink(receiveCompletion: { error in
print("copletion")
}, receiveValue: { count in
print ("\(count)")
done = true
})
while (!done) {}
This originally came up because I was flat mapping to the publisher after a json was decoded to write to the disc.
Ha, this is a deadlock. Just there:
while (!done) {}
The write publisher is documented to complete on the main thread by default. But it can't, because the main thread is busy waiting for the done
flag. The completion is scheduled... but it can never be executed, and the done
flag remains false.
So... As a general rule, be synchronous if you can, because it's just so much simpler! Do you really need Combine in a command line app?
// Synchronous database access
let count = try dbPool.write { db -> Int in
let league = League(id: "123", name: "foo", alias: "foo")
try league.insert(db)
return try League.fetchCount(db)
}
// Just use count already
print(count)
If you must use asynchronous APIs, then... use another waiting technique. There is no one-size-fits-all solution, so I'll let you find the best solution that matches your real app.
Edit: you may look for solutions based on RunLoop, dispatchMain, DispatchSemaphore, or DispatchGroup... One of them should do the trick.
I'm dumb. Thats what I get for doing things at night after 10 hrs of work. ;-) Works great when I move off main. ;-)
Love GRDB and this library. I used GRDB in the Neil Young Archives app and it was super valuable.
I'm super glad I could help you making a super app which makes people happy 😄🎶🎸
I am trying the following code with combine on a DBPool.
however the sink or any other calls inserted in the chain are never called when the publisher completes.