Skip to content

database-ktx: add callbackFlow for eventlisteners #4012

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

Merged
merged 11 commits into from
Sep 23, 2022
Merged

Conversation

thatfiredev
Copy link
Member

Part of go/kotlin-flows-firebase-android

This PR should add callbackFlows for RTDB's ValueEventListener and ChildEventListener.

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Aug 19, 2022

Coverage Report 1

Affected Products

  • firebase-database-ktx

    Overall coverage changed from 77.78% (4f24be3) to 15.56% (65c85df) by -62.22%.

    FilenameBase (4f24be3)Merge (65c85df)Diff
    ChildEvent.kt?0.00%?
    Database.kt77.78%17.07%-60.70%

Test Logs

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/IOdJ1lMy82.html

@github-actions
Copy link
Contributor

github-actions bot commented Aug 19, 2022

Unit Test Results

  4 files   -    391    4 suites   - 391   14s ⏱️ - 16m 31s
13 tests  - 4 702  13 ✔️  - 4 678  0 💤  - 22  0  - 2 
13 runs   - 4 718  13 ✔️  - 4 694  0 💤  - 22  0  - 2 

Results for commit b2b7b7b. ± Comparison against base commit 4f24be3.

♻️ This comment has been updated with latest results.

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Aug 19, 2022

Size Report 1

Affected Products

  • firebase-database-ktx

    TypeBase (4f24be3)Merge (65c85df)Diff
    aar7.23 kB22.6 kB+15.3 kB (+212.2%)
    apk (release)2.08 MB2.08 MB+3.67 kB (+0.2%)

Test Logs

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/IopnBF3HwG.html

fun Query.snapshots() = callbackFlow<DataSnapshot> {
val listener = addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
trySend(snapshot)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For 7235473 we went with trySendBlocking is there any difference between cases?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When using trySendBlocking Android Studio shows me this warning:

Screenshot 2022-08-19 at 16 26 25

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I think it is a false positive in the linter.
  2. That said, it looks like the events are dispatched on the UI thread, so it's not ok to directly trySendBlocking:

imo instead we can do the same thing we did for firestore, something like

Suggested change
trySend(snapshot)
someExecutor.execute(() -> trySendBlocking(snapshot));

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vkryachko Looks like firestore's background executor uses a ThreadPool with 4 threads:

public static final Executor BACKGROUND_EXECUTOR =
new ThrottledForwardingExecutor(
ASYNC_THREAD_POOL_MAXIMUM_CONCURRENCY, AsyncTask.THREAD_POOL_EXECUTOR);

private static final int ASYNC_THREAD_POOL_MAXIMUM_CONCURRENCY = 4;

Should we also use a ThreadPool for RTDB?

Suggested change
trySend(snapshot)
Executors.newFixedThreadPool(nThreads = 4).execute {
trySendBlocking(ChildEvent.Added(snapshot, previousChildName))
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vkryachko You were right, it was a false-positive in the linter. After the AGP7 update, the lint warning went away.

But my question on what executor we'll want to use remains.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if that is safe, i.e. isn't in happening on the UI thread?

@maneesht what are your thoughts?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like scheduleNow() delegates to DefaultRunLoop which uses a ScheduledThreadPoolExecutor , so it doesn't block the UI Thread.

public DefaultRunLoop() {
int threadsInPool = 1;
ThreadFactory threadFactory = new FirebaseThreadFactory();
executor =
new ScheduledThreadPoolExecutor(threadsInPool, threadFactory) {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My only concern with this is that we would end up blocking other operations within the Repo's actions. Maybe we should create a new executor solely for this? As RTDB only has one ATM

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought this through a bit more, and let's go ahead and just use the default run loop. If we feel like there's a performance gain, we can always change this in a future patch.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into it @maneesht !

@vkryachko vkryachko requested a review from maneesht August 19, 2022 18:43
@thatfiredev
Copy link
Member Author

@vkryachko I changed the Flows to be properties instead of functions. Please take a second look

@thatfiredev thatfiredev merged commit 3872957 into master Sep 23, 2022
@thatfiredev thatfiredev deleted the rpf-add-rtdb-flow branch September 23, 2022 12:56
@firebase firebase locked and limited conversation to collaborators Oct 24, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants