Skip to content

Remove synchronized blocks from ApkInstaller #4486

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 3 commits into from
Jan 4, 2023

Conversation

lfkellogg
Copy link
Contributor

@lfkellogg lfkellogg commented Dec 22, 2022

Uses a TaskCompletionSourceCache, which allows caching tasks which can then be resolved later in a thread-safe manner.

@google-oss-bot
Copy link
Contributor

1 Warning
⚠️ Did you forget to add a changelog entry? (Add the 'no-changelog' label to the PR to silence this warning.)

Generated by 🚫 Danger

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Dec 22, 2022

Coverage Report 1

Affected Products

  • firebase-appdistribution

    Overall coverage changed from ? (a28c43e) to 77.08% (c2e4d4d) by ?.

    43 individual files with coverage change

    FilenameBase (a28c43e)Merge (c2e4d4d)Diff
    AabUpdater.java?98.67%?
    ApkInstaller.java?100.00%?
    ApkUpdater.java?93.97%?
    AppDistributionReleaseImpl.java?100.00%?
    AppDistributionReleaseInternal.java?100.00%?
    AppIconSource.java?84.62%?
    AutoValue_AppDistributionReleaseImpl.java?65.45%?
    AutoValue_AppDistributionReleaseInternal.java?71.58%?
    AutoValue_ImageUtils_ImageSize.java?35.00%?
    AutoValue_TesterApiDisabledErrorDetails.java?29.41%?
    AutoValue_TesterApiDisabledErrorDetails_HelpLink.java?54.17%?
    AutoValue_UpdateProgressImpl.java?65.96%?
    ErrorMessages.java?0.00%?
    FeedbackActivity.java?1.12%?
    FeedbackSender.java?84.62%?
    FirebaseAppDistributionExceptions.java?80.00%?
    FirebaseAppDistributionFileProvider.java?0.00%?
    FirebaseAppDistributionImpl.java?90.00%?
    FirebaseAppDistributionLifecycleNotifier.java?92.91%?
    FirebaseAppDistributionNotificationsManager.java?87.18%?
    FirebaseAppDistributionRegistrar.java?86.27%?
    FirebaseAppDistributionTesterApiClient.java?88.54%?
    HttpsUrlConnectionFactory.java?50.00%?
    ImageUtils.java?100.00%?
    InstallActivity.java?2.67%?
    LogWrapper.java?100.00%?
    NewReleaseFetcher.java?80.85%?
    PackageInfoUtils.java?42.86%?
    ReleaseIdentifier.java?85.54%?
    ReleaseUtils.java?83.33%?
    ScreenshotTaker.java?41.18%?
    SequentialReference.java?100.00%?
    SignInResultActivity.java?0.00%?
    SignInStorage.java?100.00%?
    TakeScreenshotAndStartFeedbackActivity.java?0.00%?
    TaskCache.java?100.00%?
    TaskCompletionSourceCache.java?73.91%?
    TaskUtils.java?92.50%?
    TesterApiDisabledErrorDetails.java?93.75%?
    TesterApiHttpClient.java?90.18%?
    TesterSignInManager.java?96.12%?
    UpdateProgressImpl.java?100.00%?
    UpdateTaskImpl.java?76.00%?

Test Logs

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

@github-actions
Copy link
Contributor

github-actions bot commented Dec 22, 2022

Unit Test Results

166 tests   166 ✔️  48s ⏱️
  16 suites      0 💤
  16 files        0

Results for commit bec32df.

♻️ This comment has been updated with latest results.

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Dec 22, 2022

Size Report 1

Affected Products

  • base

    TypeBase (a28c43e)Merge (c2e4d4d)Diff
    apk (aggressive)?8.39 kB? (?)
    apk (release)?8.65 kB? (?)
  • firebase-annotations

    TypeBase (a28c43e)Merge (c2e4d4d)Diff
    apk (aggressive)?8.39 kB? (?)
    apk (release)?9.46 kB? (?)
  • firebase-appdistribution

    TypeBase (a28c43e)Merge (c2e4d4d)Diff
    aar?154 kB? (?)
    apk (aggressive)?833 kB? (?)
    apk (release)?2.01 MB? (?)
  • firebase-appdistribution-api

    TypeBase (a28c43e)Merge (c2e4d4d)Diff
    aar?16.0 kB? (?)
    apk (aggressive)?95.8 kB? (?)
    apk (release)?706 kB? (?)
  • firebase-common

    TypeBase (a28c43e)Merge (c2e4d4d)Diff
    aar?67.4 kB? (?)
    apk (aggressive)?95.1 kB? (?)
    apk (release)?700 kB? (?)
  • firebase-components

    TypeBase (a28c43e)Merge (c2e4d4d)Diff
    aar?44.9 kB? (?)
    apk (aggressive)?8.68 kB? (?)
    apk (release)?33.6 kB? (?)
  • firebase-installations

    TypeBase (a28c43e)Merge (c2e4d4d)Diff
    aar?55.0 kB? (?)
    apk (aggressive)?96.6 kB? (?)
    apk (release)?724 kB? (?)
  • firebase-installations-interop

    TypeBase (a28c43e)Merge (c2e4d4d)Diff
    aar?8.05 kB? (?)
    apk (aggressive)?65.0 kB? (?)
    apk (release)?651 kB? (?)

Test Logs

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

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Dec 22, 2022

Startup Time Report 1

Note: Layout is sometimes suboptimal due to limited formatting support on GitHub. Please check this report on GCS.

Startup time comparison between the CI merge commit (c2e4d4d) and the base commit (a28c43e) are not available.

No macrobenchmark data found for the base commit (a28c43e). Analysis for the CI merge commit (c2e4d4d) can be found at:

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

@lfkellogg lfkellogg force-pushed the lk/no-sync-apk-installer branch from 8432a15 to e452ad6 Compare December 22, 2022 22:22
@lfkellogg lfkellogg changed the base branch from fad/in-app-feedback to lk/harden-signinstorage December 22, 2022 22:23
Base automatically changed from lk/harden-signinstorage to fad/in-app-feedback January 3, 2023 18:21
@lfkellogg lfkellogg force-pushed the lk/no-sync-apk-installer branch from e452ad6 to ec13be6 Compare January 3, 2023 18:34
@lfkellogg lfkellogg requested a review from kaibolay January 3, 2023 23:55
@@ -84,12 +69,9 @@ private void startInstallActivity(String path, Activity currentActivity) {
}

void trySetInstallTaskError() {
Copy link
Contributor

Choose a reason for hiding this comment

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

does this still need to be called "try"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll do you one better: this method doesn't even need to exist! It's only called once so I'm going to inline it.

* Constructor for a {@link TaskCompletionSourceCache} that controls access using its own
* sequential executor backed by the given base executor.
*
* @param baseExecutor Executor (typically {@link Lightweight}) to back the sequential executor.
Copy link
Contributor

Choose a reason for hiding this comment

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

Are there any cases where this should not (or is not) the "lightweight" executor?

If so, I think it should be documented which circumstances require a different executor. Does it depend on what TaskCompletionSourceProducer.produce() does?

If not, maybe change "typically" to "always" and annotate the consturctor parameter accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. It does depend on what TaskCompletionSourceProducer.produce() does. I've reworded it.

@@ -144,5 +145,12 @@ static <T> UpdateTask onSuccessUpdateTask(
return updateTask;
}

/** Set a {@link TaskCompletionSource} to be resolved with the result of another {@link Task}. */
static <T> void shadowTask(TaskCompletionSource<T> taskCompletionSource, Task<T> task) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can/should this be a method on TaskCompletionSource itself?
If so, can/should it use the TaskCompletionsSource's executor instead of the "direct" one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TaskCompletionSource is provided by the play-services library, so we can't add it there (although we could file a feature request).

Also just a note: TaskCompletionSource doesn't actually have its own executor. When you set a result on it, it passes that through to the underlying TaskImpl, which executes any handlers on the executors that were specified when they were added. Using direct executor here ensures that any handlers that were themselves added using a direct executor will behave as expected: they'll be executed on the thread that set the result. (I'll add a note to that effect).

private final Object installTaskLock = new Object();

ApkInstaller(FirebaseAppDistributionLifecycleNotifier lifeCycleNotifier) {
ApkInstaller(
Copy link
Contributor

Choose a reason for hiding this comment

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

should this constructor be annotated with @VisibleForTesting?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep!

this(FirebaseAppDistributionLifecycleNotifier.getInstance());
}

void onActivityStarted(@Nullable Activity activity) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This method was literally doing nothing

Comment on lines -64 to -65
public void
setCurrentActivity_appInForegroundAfterAnInstallAttempt_installIntentOnCurrentActivity() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was testing the onActivityStarted() that I removed.

firebaseAppDistribution.signOutTester();
awaitAsyncOperations(backgroundExecutor);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noticed this test was flaky without this, which makes sense since the update to SharedPreferences happens on the background thread.

private final Object installTaskLock = new Object();

ApkInstaller(FirebaseAppDistributionLifecycleNotifier lifeCycleNotifier) {
ApkInstaller(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep!

@@ -84,12 +69,9 @@ private void startInstallActivity(String path, Activity currentActivity) {
}

void trySetInstallTaskError() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll do you one better: this method doesn't even need to exist! It's only called once so I'm going to inline it.

* Constructor for a {@link TaskCompletionSourceCache} that controls access using its own
* sequential executor backed by the given base executor.
*
* @param baseExecutor Executor (typically {@link Lightweight}) to back the sequential executor.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. It does depend on what TaskCompletionSourceProducer.produce() does. I've reworded it.

@@ -144,5 +145,12 @@ static <T> UpdateTask onSuccessUpdateTask(
return updateTask;
}

/** Set a {@link TaskCompletionSource} to be resolved with the result of another {@link Task}. */
static <T> void shadowTask(TaskCompletionSource<T> taskCompletionSource, Task<T> task) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

TaskCompletionSource is provided by the play-services library, so we can't add it there (although we could file a feature request).

Also just a note: TaskCompletionSource doesn't actually have its own executor. When you set a result on it, it passes that through to the underlying TaskImpl, which executes any handlers on the executors that were specified when they were added. Using direct executor here ensures that any handlers that were themselves added using a direct executor will behave as expected: they'll be executed on the thread that set the result. (I'll add a note to that effect).

@lfkellogg lfkellogg merged commit 8a54521 into fad/in-app-feedback Jan 4, 2023
@lfkellogg lfkellogg deleted the lk/no-sync-apk-installer branch January 4, 2023 14:54
lfkellogg added a commit that referenced this pull request Jan 5, 2023
* Remove synchronized blocks from ApkInstaller

* Fix broken test

* Address Kai's feedback
kaibolay pushed a commit that referenced this pull request Jan 23, 2023
* Remove synchronized blocks from ApkInstaller

* Fix broken test

* Address Kai's feedback
lfkellogg added a commit that referenced this pull request Jan 25, 2023
* Remove synchronized blocks from ApkInstaller

* Fix broken test

* Address Kai's feedback
lfkellogg added a commit that referenced this pull request Jan 25, 2023
* Remove synchronized blocks from ApkInstaller

* Fix broken test

* Address Kai's feedback
@firebase firebase locked and limited conversation to collaborators Feb 4, 2023
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.

3 participants