Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved support for values observation #435

Merged
merged 109 commits into from
Nov 2, 2018
Merged

Conversation

groue
Copy link
Owner

@groue groue commented Oct 25, 2018

This PR addresses a few use cases that are not quite well addressed today:

  • Allow database observation from DatabaseReader.

    Some users use the DatabaseWriter and DatabaseReader protocols in order to prevent some parts of their apps from writing in the database.

    Unfortunately, DatabaseReader does not allow database observation: only DatabaseWriter has the fundamental add(transactionObserver:extent:) method. The consequence is that one must grant write access to components that want to observe the database.

    This constraint hinders the usefulness of those protocols: we should lift it.

  • Help supporting more reactive engines

    GRDB currently has the RxGRDB companion library, based on RxSwift.

    But there are other reactive engines out there. Supporting more of them is a much-welcomed contribution. For example, we may well have support for ReactiveKit soon, thanks to @cfilipov.

    Robust scheduling of database changes is a tough job, though. Even if FetchedRecordsController and RxGRDB have well identified most application needs, they perform a lot of duplicated work, just to accomplish the most requested feature: notification on the main thread of fresh values.

    In the current state of GRDB, supporting more reactive engines would mean more duplication of delicate multi-threaded code, which means more opportunities to introduce subtle bugs. The last thing users want is database notifications that are not scheduled on the correct dispatch queue, are missing, are not well-ordered, are asynchronously dispatched when they expect a synchronous callback, block all writes in their efficient database pool. Those are only a few of the traps that lure around the topic of values observation.

    Values observation should be a built-in GRDB service, ready made for reactive engines. The feature set should include:

    • a dispatch queue for notified values.
    • synchronous or asynchronous dispatch of initial values, when needed (synchronous dispatch, especially on the main thread, is necessary in order to avoid flashes of missing content).
    • deduplication of identical values at the database level.
  • Help avoiding reactive engines

    Reactive Programming is fashionable, but GRDB is not a library that tells you how you are supposed to architecture your applications.

    The only high-level value observation tool that ships with GRDB is FetchedRecordsController, which mimics NSFetchedResultsController. It is not quite as versatile and easy to use as RxGRDB. For example, FetchedRecordsController won't let you easily observe a single record such as Player.filter(key: 42).

    We need an improved value observation API, that would push FetchedRecordsController into its niche use-case: table view animations.

  • Observation of fetch requests that write

    This one caught me by surprise. Well, yes indeed, some requests need temporary tables and indexes in order to be efficiently performed: such requests need to write in the database in order to fetch their results.

    They are not at all supported by current value observation tools, that always execute their requests in a read-only environment, and throw an error whenever a request attempts at writing in the database.

    There is no reason those requests should not be granted with the same ultra-robust observation of fresh values that read-only requests can profit from.

  • When observing values, transactions are not interesting, but actual changes are

    The default observation behavior should filter out consecutive identical values at the database level. This comparisons must not block the main queue, or accesses to the database.

@cfilipov
Copy link

Very nice! Indeed I did notice there was a lot more multi-threaded logic than I expected when porting RxGRDB. I was expecting more of a thin API wrapper. This sounds like it should bring it closer to that which would mean less duplication between reactive implementations.

@groue
Copy link
Owner Author

groue commented Oct 25, 2018

Yes @cfilipov, it happens that your recent questions align quite well with some needs of an app I'm currently working on. Right on time 😄

@groue groue added this to the GRDB 3.5.0 milestone Nov 2, 2018
@groue groue changed the base branch from master to development November 2, 2018 15:46
@groue groue merged commit 0cbf259 into development Nov 2, 2018
@groue groue deleted the feature/ValueObservation branch November 2, 2018 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants