-
Notifications
You must be signed in to change notification settings - Fork 617
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
Conversation
Coverage Report 1Affected Products
Test Logs |
Size Report 1Affected Products
Test Logs |
fun Query.snapshots() = callbackFlow<DataSnapshot> { | ||
val listener = addValueEventListener(object : ValueEventListener { | ||
override fun onDataChange(snapshot: DataSnapshot) { | ||
trySend(snapshot) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I think it is a false positive in the linter.
- That said, it looks like the events are dispatched on the UI thread, so it's not ok to directly
trySendBlocking
:
Line 25 in 58c1677
this.handler = new Handler(Looper.getMainLooper());
imo instead we can do the same thing we did for firestore, something like
trySend(snapshot) | |
someExecutor.execute(() -> trySendBlocking(snapshot)); |
There was a problem hiding this comment.
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:
Lines 42 to 44 in d50a3d1
public static final Executor BACKGROUND_EXECUTOR = | |
new ThrottledForwardingExecutor( | |
ASYNC_THREAD_POOL_MAXIMUM_CONCURRENCY, AsyncTask.THREAD_POOL_EXECUTOR); |
Line 30 in d50a3d1
private static final int ASYNC_THREAD_POOL_MAXIMUM_CONCURRENCY = 4; |
Should we also use a ThreadPool for RTDB?
trySend(snapshot) | |
Executors.newFixedThreadPool(nThreads = 4).execute { | |
trySendBlocking(ChildEvent.Added(snapshot, previousChildName)) | |
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
Lines 65 to 69 in 6a566dd
public DefaultRunLoop() { | |
int threadsInPool = 1; | |
ThreadFactory threadFactory = new FirebaseThreadFactory(); | |
executor = | |
new ScheduledThreadPoolExecutor(threadsInPool, threadFactory) { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 !
firebase-database/ktx/src/main/kotlin/com/google/firebase/database/ktx/Database.kt
Outdated
Show resolved
Hide resolved
@vkryachko I changed the Flows to be properties instead of functions. Please take a second look |
Part of go/kotlin-flows-firebase-android
This PR should add callbackFlows for RTDB's
ValueEventListener
andChildEventListener
.