-
Notifications
You must be signed in to change notification settings - Fork 438
Description
Summary: Currently, different streaming queries don't know whether they're happening as part of the same DB transaction, or, it seems like there's no way to be notified when a transaction ends. I'm currently trying to build what I think's a pretty good approach to app state persistence, and this is currently in the way. The proposed fix seems simple.
use case:
In my app, and probably in every app I make from now on, I use a kind of persisted signal (pignal) (a lazy observable that persists to storage) for important state. Writes to a signal will be transmitted to the db, and writes to the db will update the signal (the signal subscribes to the db using a streaming select query).
(Also, though this is a minor feature, values are timestamped, which I think may improve behaviour where two isolates are writing at the same time? EG, if one of the isolates sets one of its pignals to 'a' and then sends a write to the db, then the db completes a write from the other isolate of 'b' and so the db tells the pignal that it must now be 'b', and only after that does the pignal's write complete, and then the db tells it it must be 'a' after all. With timestamps it ignores the 'b' write.).
The Signals library supports transactions (batch), wherein multiple signals can be updated without immediately triggering effects, delaying them until the end of the batch, and of course drift supports transactions too, but I can't see a way to get a DB transaction to translate into one Signal transaction.
Right now, a batch of changes in the DB will cause a series of many incomplete/incorrect pignal reactions.
(to get even more specific, the motivating incident was, I'm making a timer app, it has two lists of timers, (pinned timers and timers that're going to be cleaned up automatically if the user leaves them sitting around for too long). The lists are represented by pignals. I'd like the background thread to maintain a third signal that just aggregates both lists as a set, for detecting the creation and deletion of timers. Sometimes the user drags a timer from one list to the other. Currently, when this happens, the aggregate set would erroniously undergo two events (Though I should disclose that for hairy reasons that aren't worth getting into, I don't actually have to fix this in this case. A hack will do. but I could easily imagine that I might have needed this if things had been just a little different!))
proposed solution:
A pair of methods drift.addTransactionBeginListener(()=> signals.startBatch()) and drift.addTransactionEndListener(()=> signals.endBatch()) would do it. These listeners would be invoked before and after every change the DB reports.