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

Speculative Fix for WorkManager not Initialized Crash #1721

Merged
merged 2 commits into from
Feb 22, 2023

Conversation

nan-li
Copy link
Contributor

@nan-li nan-li commented Jan 17, 2023

Description

One Line Summary

This is a speculative fix for the non-reproducible WorkManager is not Initialized Crash we have been seeing many reports of.

Details

Motivation

Please see issue this aims to address: #1672.

We don't completely understand this crash, so this fix is speculative and based off a response from Google Issue Tracker, though the responder may not completely understand how OneSignal is used in applications.

Scope

  • Before using WorkManager, we will check for its existence. Else, in rare cases that were crashing, initialize it ourselves.
  • We use a method to check if WorkManager is initialized in the process.

⚠️ Concerns ⚠️

We take over and initialize WorkManager if we see it is nil, which so far is rare.

Perhaps this crash happens because the default WorkManager initializer hasn't run yet, but is about to... In which case, right after we initialize WorkManager, the default initializer will trigger a WorkManager is already initialized exception. But, maybe that's not what is happening and this secondary crash doesn't happen.

Before accessing and initializing WorkManager ourselves, we check if it's already initialized using the same logic that the work library provides in a 2.8.0-alpha02 release. However, could we have a race condition such that when we check, it is nil, but momentarily after, it becomes initialized, while we go and try to initialize it? This could create issues that didn't exist before, but I don't think so as the Android library contains synchronization and we do too.

Testing

Unit testing

No unit test was added as it is hard to unit test this.

  • we would have to test double Android library components
  • androidx.work.testing package didn't have anything for our use case either

Manual testing

Limited ability to test manually.

  • Tested normal app flow in an emulator

Affected code checklist

  • Notifications
    • Display
    • Open
    • Push Processing
    • Confirm Deliveries
  • Outcomes
  • Sessions
  • In-App Messaging
  • REST API requests
  • Public API changes

Checklist

Overview

  • I have filled out all REQUIRED sections above
  • PR does one thing
  • Any Public API changes are explained in the PR details and conform to existing APIs

Testing

  • I have included test coverage for these changes, or explained why they are not needed
  • All automated tests pass, or I explained why that is not possible
  • I have personally tested this on my device, or explained why that is not possible

Final pass

  • Code is as readable as possible.
  • I have reviewed this PR myself, ensuring it meets each checklist item

This change is Reviewable

@nan-li nan-li force-pushed the fix/speculative_work_manager_crash_fix branch 4 times, most recently from 7072090 to a16ae65 Compare January 19, 2023 22:02
* Before using WorkManager, check for its existence. Else, in rare cases that were crashing, initialize it ourselves.
* Provides a method to check if WorkManager is initialized in this process.
  - This is effectively the `WorkManager.isInitialized()` public method introduced in `androidx.work:work-*:2.8.0-alpha02`.
  - Please see https://android-review.googlesource.com/c/platform/frameworks/support/+/1941186 for the library's implementation
@nan-li nan-li force-pushed the fix/speculative_work_manager_crash_fix branch from a16ae65 to 51f1399 Compare January 19, 2023 23:43
@nan-li nan-li requested a review from jkasten2 January 24, 2023 19:39
Copy link
Member

@jkasten2 jkasten2 left a comment

Choose a reason for hiding this comment

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

I think this PR is safe to put into main and a normal release.

This won't introduce any new crashes, the concern of "WorkManager is already initialized" wouldn't happen with the default work manager initialization. This is because they use a Provider which always runs before Application.onCreate per Android's docs and what we have observed in our own testing. However, we have seen a report of one expectation to this where it can be completely skipped and never runs the Provider. This PR should fix this, and hopefully is this is the same root issue for the other crash reports.

If the app is initializing WorkManager themselves there is a very small possibility "WorkManager is already initialized" could happen instead of "WorkManager not Initialized". However this could only happen if there was a pre-existing race condition with OneSignal and the app's custom initializer anyway.

@nan-li
Copy link
Contributor Author

nan-li commented Jan 27, 2023

Consider if we will override an app's custom initializer if there is one.

@jkasten2
Copy link
Member

Consider if we will override an app's custom initializer if there is one.

I believe our isInitialized() would detect that, then we would skip WorkManager.initialize so we won't overwrite theirs.

@nan-li
Copy link
Contributor Author

nan-li commented Jan 28, 2023

I was thinking about WorkManager.getInstance(context) (this code here). This method uses the same logic as our isInitialized() check and if null and there is a custom initializer, it would create WorkManager with that configuration.

But we would sort of intercept that early and create it ourselves.

@jkasten2
Copy link
Member

True, but if they didn't run their custom initializer soon enough today they would be seeing "WorkManager not Initialized" being thrown by the OneSIgnal SDK today.

I think this is a compatibility issue we should try to improve on in it's own PR, but we need to come up with a strategy and / or an API first.

@Martin-Gonzalez90
Copy link

Martin-Gonzalez90 commented Feb 22, 2023

Any ETA for this merge?
Can be please be merged in a 4.x release as well, so we don't have to jump to version 5 🙏

Copy link
Contributor

@jennantilla jennantilla left a comment

Choose a reason for hiding this comment

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

Interesting potential for conflict with a custom initializer not running soon enough. Very interested in observing future strategizing on this compatibility issue.

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

Successfully merging this pull request may close these issues.

4 participants