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

Deprecate existing WorkerBinder.bind methods and provide recommended bindTo methods with RibDispatchers.Default #594

Conversation

FranAguilera
Copy link
Contributor

@FranAguilera FranAguilera commented Jun 7, 2023

Description:

Since #553 we added support to specify on which CoroutineDispatcher are presidio Worker will be bound. RibDispatchers.Unconfined was added as a default parameter in order to keep existing behavior and not be a breaking change.

Still, binding by default on the current caller thread within interactor means that by default we are binding workers on main UI thread leading to potential jank ANR etc just for binding those workers.

This is specially problematic when the list of workers being bound keeps increasing (e.g. hypothetically if we have 100 workers and each bind takes at least 50 ms this will result on the UI thread being blocked for at least 5000ms)

Proposal is to deprecate existing methods and provide new methods that by default will bind on Ribdispatchers.DEFAULT (similarly to RibCoroutineWorker). Still if there is a need for a Worker to change the thread where it will be bound we can rely on coroutineContext property to be overriden as following (default value is EmptyCoroutineContext):

  class MyUiWorker:com.uber.rib.core.Worker{
    override val coroutineContext: CoroutineContext = RibDispatchers.Main
  }

Demo call:

worker.bindTo(interactor)

NOTE: For calling on existing java files -> WorkerBinderKt.bindTo(ribWorker, this));

Related issue(s):

#595

Verified via Unit tests

@FranAguilera FranAguilera requested a review from tyvsmith June 7, 2023 18:59
@FranAguilera FranAguilera marked this pull request as draft June 7, 2023 18:59
@FranAguilera FranAguilera changed the title Add new WorkerBinder methods that runs off main thread [Draft] Add new WorkerBinder methods that runs off main thread Jun 7, 2023
@FranAguilera FranAguilera force-pushed the deprecate_existing_worker_binding_apis branch from 80d64b9 to a4eb507 Compare June 7, 2023 19:03
Deprecates existing WorkerBinder.bind methods that currently defaults to RibDispatchers.Unconfined in favor of bindInteractor/binPresenter methods that will be bound by default off the main thread (Worker still can override this binding individually if needed)
@FranAguilera FranAguilera force-pushed the deprecate_existing_worker_binding_apis branch from a4eb507 to af354f2 Compare June 7, 2023 19:15
@FranAguilera FranAguilera added the Android Android related tickets label Jun 7, 2023
@FranAguilera FranAguilera changed the title [Draft] Add new WorkerBinder methods that runs off main thread Add new WorkerBinder methods that runs off main thread Jun 7, 2023
@FranAguilera FranAguilera marked this pull request as ready for review June 7, 2023 19:24
@FranAguilera FranAguilera changed the title Add new WorkerBinder methods that runs off main thread Deprecate existing WorkerBinder.bind methods + add new binding methods with RibDispatchers.Default Jun 7, 2023
@FranAguilera FranAguilera requested a review from psteiger June 7, 2023 21:21
@FranAguilera FranAguilera changed the title Deprecate existing WorkerBinder.bind methods + add new binding methods with RibDispatchers.Default Provide migration APIs and deprecate existing WorkerBinder.bind methods with default RibDispatchers.Unconfined Jun 8, 2023
@FranAguilera FranAguilera requested a review from psteiger June 8, 2023 06:43
@FranAguilera

This comment was marked as outdated.

@FranAguilera FranAguilera force-pushed the deprecate_existing_worker_binding_apis branch from 97e452a to 5a58c21 Compare June 8, 2023 07:08
@FranAguilera FranAguilera force-pushed the deprecate_existing_worker_binding_apis branch from 5a58c21 to 60660e8 Compare June 8, 2023 07:17
@FranAguilera FranAguilera force-pushed the deprecate_existing_worker_binding_apis branch from fb98a37 to 2759b49 Compare June 8, 2023 07:36
* @return [WorkerUnbinder] to unbind [Worker]'s lifecycle.
*/
@JvmStatic
public fun bindToPresenter(
Copy link
Member

Choose a reason for hiding this comment

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

This looks like new functionality added that isn't needed for these changes (unless I missed it's usage) where we support binding to a list.

  1. Should this be a separate PR if we want a new puiblic API.
  2. Rather in this diff or on the next, probably rename to bindToPresenters (plural)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We've been providing these APIs (WorkerBinder.bind(interactor, listOfWorkers)/ WorkerBinder.bind(presenter, listOfWorkers) for a while.

Part of the goal of this PR is to deprecate existing WorkerBinder.bind methods given that the methods with 2 parameter call takes a default RibDispatchers.Unconfined which often times results in binding on main thread.

Was thinking that adding new methods (bindToInteractor, bindToPresenter) that are opinionated on using to RibDispatchers.Default to prevent further additions of WorkerBinder.bind on main thread (we can easily rely on static analysis to force everyone to use the new API when new WorkerBinder additions).

Also another important caveat, if there is still a need for a legacy worker to be bound on the main thread this can be achieved by overriding Worker's coroutineContext property (this will ignore the default Dispatchers specified on WorkerBinder call)

@FranAguilera FranAguilera marked this pull request as draft June 12, 2023 18:57
@FranAguilera FranAguilera force-pushed the deprecate_existing_worker_binding_apis branch from 1b1b4e8 to 27364b1 Compare June 12, 2023 19:18
@FranAguilera FranAguilera changed the title Provide migration APIs and deprecate existing WorkerBinder.bind methods with default RibDispatchers.Unconfined Deprecate existing WorkerBinder.bind methods and provide recommended bindTo methods with RibDispatchers.Default Jun 12, 2023
@FranAguilera FranAguilera marked this pull request as ready for review June 12, 2023 19:20
@FranAguilera FranAguilera requested a review from tyvsmith June 12, 2023 19:20
@FranAguilera FranAguilera force-pushed the deprecate_existing_worker_binding_apis branch from 27364b1 to 1cfca74 Compare June 12, 2023 19:24
@FranAguilera FranAguilera requested a review from psteiger June 12, 2023 22:01
Revert "Move extensions functions to its own file"

This reverts commit 675fdf4e77cfd550658bc4a3989824dd79308b87.
@FranAguilera FranAguilera force-pushed the deprecate_existing_worker_binding_apis branch from 675fdf4 to 9bf6e89 Compare June 12, 2023 22:06
@psteiger
Copy link
Contributor

I don't have any conceptual objections. Exposing new API as public top-level function instead of nested inside WorkerBinder object is nice. And deprecating the previous API instead of changing it keeps retro-compat.

With that said, maybe we should consider deprecating Worker in favor of RibCoroutineWorker. I'm not sure it's worth to keep evolving Worker API. But if it's being done as a smoother transition pathway, I'm ok with it.

@FranAguilera
Copy link
Contributor Author

I don't have any conceptual objections. Exposing new API as public top-level function instead of nested inside WorkerBinder object is nice. And deprecating the previous API instead of changing it keeps retro-compat.

With that said, maybe we should consider deprecating Worker in favor of RibCoroutineWorker. I'm not sure it's worth to keep evolving Worker API. But if it's being done as a smoother transition pathway, I'm ok with it.

I completely agree with eventually fully deprecating this old worker. The only missing piece for RibCoroutineWorker is monitoring option for binding duration (but given that by default is bound on RibDispatchers.Default. there is no much of a concern). Also we can validate a few of this RibCoroutineWorkers in prod and if no issues found we can completely mark worker as deprecated

@FranAguilera
Copy link
Contributor Author

I don't have any conceptual objections. Exposing new API as public top-level function instead of nested inside WorkerBinder object is nice. And deprecating the previous API instead of changing it keeps retro-compat.
With that said, maybe we should consider deprecating Worker in favor of RibCoroutineWorker. I'm not sure it's worth to keep evolving Worker API. But if it's being done as a smoother transition pathway, I'm ok with it.

I completely agree with eventually fully deprecating this old worker. The only missing piece for RibCoroutineWorker is monitoring option for binding duration (but given that by default is bound on RibDispatchers.Default. there is no much of a concern). Also we can validate a few of this RibCoroutineWorkers in prod and if no issues found we can completely mark worker as deprecated

Actually, after thinking about a bit more I don't think we should keep expanding this WorkerBinder API given is going to be deprecated soon in favor of RibCoroutineWorker.

I was thinking though to add a migration mechanism to change the WorkerBinderDispatcher to other than Unconfined. In that manner we can migrate internally all worker binding outside Ui thread in a safe manner

@FranAguilera FranAguilera marked this pull request as draft June 13, 2023 18:43
@FranAguilera
Copy link
Contributor Author

Will be putting a new PR for migration API options

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Android Android related tickets
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants