launchdarkly / android-client-sdk

LaunchDarkly Client-side SDK for Android
Other
45 stars 23 forks source link

Tried to update LDClients with network connectivity status, but LDClient has not yet been initialized. #218

Closed worstkiller closed 1 year ago

worstkiller commented 1 year ago

Describe the bug This issue is not happening on the development devices so won't be able to add how and when it gets reproduced. but from logs it seems this is happening

To reproduce Not able to reproduce on staging environment or device.

Expected behavior SDK should be able to initialize the client properly and load the remote values properly. currently we can see from stack track that sometimes its failing to load the client properly.

Logs Tried to update LDClients with network connectivity status, but LDClient has not yet been initialized.

  at dalvik.system.VMStack.getThreadStackTrace(VMStack.java)
    at java.lang.Thread.getStackTrace(Thread.java:1841)
    at timber.log.Timber$Forest.e(SourceFile:337)
    at com.launchdarkly.sdk.android.LDTimberLogging$ChannelImpl.logInternal
    at com.launchdarkly.sdk.android.LDTimberLogging$ChannelImpl.logInternal
    at com.launchdarkly.sdk.android.LDAndroidLogging$ChannelImplBase.log(SourceFile:92)
    at com.launchdarkly.logging.LDLogger.error(SourceFile:213)
    at com.launchdarkly.sdk.android.LDClient.onNetworkConnectivityChangeInstances
    at com.launchdarkly.sdk.android.LDClient.onNetworkConnectivityChangeInstances
    at com.launchdarkly.sdk.android.ConnectivityReceiver.onReceive
    at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0$LoadedApk$ReceiverDispatcher$Args(LoadedApk.java:1806)
    at android.app.LoadedApk$ReceiverDispatcher$Args$$ExternalSyntheticLambda0.run
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:226)
    at android.os.Looper.loop(Looper.java:313)
    at android.app.ActivityThread.main(ActivityThread.java:8669)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)

SDK version 4.0.0

Language version, developer tools kotlin 1.8.0, (Android Studio Flamingo | 2022.2.1 RC 1),

OS/platform Android Version:12, SM-S134DL Model:SM-S134DL,

Additional context

We have updated to 4.0.0 but we are using initializing this way, here some code snippets

 if (!userId.isPresent()) {
                    LDUser.Builder("anonymous")
                        .anonymous(true)
                        .build()
                } else {
                    LDUser.Builder(userId.get().toString())
                        .apply {
                            if (userId.isPresent()) {
                                this.custom("user_id", "some_id")
                            }
                        }
                        .build()
                }

then passing LDUser instance below

 synchronized(this) {
                    if (null == client) {
                        client = LDClient.init(
                            application,
                            LDConfig.Builder()
                                .mobileKey(key)
                                .diagnosticOptOut(true)
                                .build(),
                            ldUser,
                            0
                        )
                        updateConfigs()
                        client!!.registerAllFlagsListener(listener)
                    } else {
                        client?.identify(ldUser)
                        client?.flush()
                    }
                }

This issue has occurred 17k times in last 30 days, so it's causing issues in our users devices and they might not be working properly. Kindly look into this when you get chance.

Thanks a lot

tanderson-ld commented 1 year ago

Hi @worstkiller . Is this the first app version you released with version 4.0.0 of our SDK? Or did some other change coincide with these logs appearing?

worstkiller commented 1 year ago

Hi @worstkiller . Is this the first app version you released with version 4.0.0 of our SDK? Or did some other change coincide with these logs appearing?

the first time we saw this issue was in 3.2.2 a few months back in January I guess. this is not our first release, later I updated sdk from 3.2.2 to 4.0.0 see if this is fixed. Also to add more this issue is not a fatal issue but we are worried if the client is working properly internally otherwise it won't be able to load new remote values and many parts won't work properly.

tanderson-ld commented 1 year ago

Thank you for the info. We will take a look, try to come up with some theories and get back to you within the next week.

tanderson-ld commented 1 year ago

Hi again @worstkiller, I just spent a bit reviewing the behavior of 3.2.2 and the changes made between 3.2.2 and 4.0.0.

The connectivity mechanisms were significantly overhauled in version 4.0.0 and so this issue won't affect 4.0.0

To address your original concern, in 3.2.2 - That error is logged if we get a connectivity update from the OS and LDClient.init(...) hadn't been called yet. This can happen during app launch/resumption from long background if the OS's connectivity state changes ( "android.net.conn.CONNECTIVITY_CHANGE"). Think race condition. Ultimately, once LDCLient.init(...) is called, the connectivity monitoring system is set up with the correct state and everything will be good from there on.

From my investigation, this should not be resulting in any issues for your customers. Please let me know if you have evidence that indicates the LDClient isn't able to provide feature flag evaluations when this error is occurring and the customer has internet at least once to synchronize the feature flag rules.