Unleash / unleash-android-proxy-sdk

https://docs.getunleash.io/unleash-android-proxy-sdk
Apache License 2.0
8 stars 16 forks source link

The current implementation of polling doesn't take into account Android app lifecycle #48

Closed bogdanzurac closed 3 months ago

bogdanzurac commented 1 year ago

Describe the bug

The current polling implementation is being handled by Kotlin Timers, as seen here:

this.timer =  timer(
            name = "unleash_toggles_fetcher",
            initialDelay = 0L,
            daemon = true,
            period = autoPollingConfig.pollRateDuration
        ) {
            updateToggles()
            if (!initialized.getAndSet(true)) {
                initFuture.complete(null)
            }
        }

The problem with this approach is that it doesn't take into account the Android Application/Activity lifecycle. Thus, the Unleash SDK doesn't stop the API polling when the app is in the background and the Kotlin Timers API doesn't know anything about Android lifecycle.

This triggers issues such as network exceptions, because Android tries to optimize battery life through Doze and kills access to the network while the device is sleeping. An example can be seen in the below screenshot, which happens after we put the device to sleep.

Steps to reproduce the bug

  1. Enable polling each 30 seconds for easy reproducibility
  2. Attach a TogglesErroredListener in order to receive logs whenever the UnleashClient encounters an API error during feature toggle refresh
  3. Build the UnleashClient and wait for it to do the initial refresh of toggles
  4. Put the device to sleep using the power button
  5. Wait for a few minutes
  6. Network errors should appear in logs from TogglesErroredListener

Expected behavior

We would expect that the SDK would take the Android lifecycle into account and either stop polling when the device is sleeping or to implement polling through Android-specific components that take Android lifecycle into account, such as Services or WorkManager.

Logs, error output, etc.

No response

Screenshots

MicrosoftTeams-image

Additional context

No response

Unleash version

0.5.0

Subscription type

Enterprise

Hosting type

Self-hosted

SDK information (language and version)

0.5.0

chriswk commented 1 year ago

Good point. I agree, I guess it's time for the SDK to actually acknowledge that it lives/exists for Android. So far there's not really been any thing in the code that is android specific, but since we call it the android-proxy-sdk I guess it makes sense to actually use android APIs. I can't promise a fix today, but I've added it to our task board for the week and I will try to get to it.

FVolodia commented 1 year ago

@chriswk Hey, any progress on that?

HenrikBacher commented 1 year ago

@chriswk any updates on this issue?

thomasheartman commented 1 year ago

Hi! 🙋🏼 Sorry for the delayed response.

Unfortunately, we've looked into this, and it's not something we will fix right away. When scoping it out, we realized it'd require rearchitecting the SDK, and we did not have the time to do that when we last looked at it. We'll have another look and reprioritize it for Q4, however. So I can't give you any status just yet, but we'll start discussions on that next week.

I hope you can find a workaround in the meantime. And of course, if you have time, you're always welcome to open a PR if you want to fix it yourself 😄 Let me know if you have any questions.

gastonfournier commented 3 months ago

This should be fixed by the new SDK that was just released: https://github.com/Unleash/unleash-android

Check out the migration guide https://github.com/Unleash/unleash-android/blob/migration-docs/docs/MigrationGuide.md

StylianosGakis commented 3 months ago

Is this one going to still be maintained or is the new one a complete replacement?

gastonfournier commented 3 months ago

Hi @StylianosGakis the idea is to move to the new one and eventually archive this one. We decided to keep it open for a while to follow up on some issues and conversations.

The main reason is that adapting this one to be an Android library wasn't easy. So we started the new repository with the barebones of an Android library and then moved the functionality to the new one. So it's a complete replacement, but it's not as simple as a version bump.