launchdarkly / python-server-sdk

LaunchDarkly Server-side SDK for Python
https://docs.launchdarkly.com/sdk/server-side/python
Other
38 stars 44 forks source link

Using ldclient during import / before main causes live updates to not show up #223

Closed davidgrohmann closed 7 months ago

davidgrohmann commented 9 months ago

This may be related to another bug report as the symptom is similar but the repro case is different 2nd call to set_config reopens the client without reopening the streaming connection · Issue #218 · launchdarkly/python-server-sdk https://github.com/launchdarkly/python-server-sdk/issues/218

Describe the bug Using ldclient during import / before the code execution gets to here: if __name__ == "__main__": Causes updates to not be visible to ldclient.variation()

To reproduce Call the code below

def __init_feature_flags_client() -> ldclient.LDClient:
    config = get_config()
    sdk_key = ssm.get_param(config.ld_sdk_key)
    ldclient.set_config(Config(sdk_key, flush_interval=5 * 60))
    return ldclient.get()

def get_ld_flag(flag_name: str, default: Any, user_context: Optional[LDUser] = None) -> Any:
    client = None
    try:
        client = ldclient.get()
    except Exception:
        __init_feature_flags_client()
        client = ldclient.get()
    if user_context is None:
        user_context = create_anonymous_user()
    result = client.variation(flag_name, user_context.to_dict(), default)
    logger.debug(f"LD FLAG EVAL: {flag_name} is {result}")
    return result

# BUT If I remove this line, everything works correctly
get_ld_flag( flag_name, ...)

if __name__ == "__main__":
   # change the value for flag in ld.com interface
   while true:
         time.sleep(1)
         get_ld_flag( flag_name, ...)  # the original value is retrieved for any flag
   # this is true for all flags not just the originally requested flag

Expected behavior A clear and concise description of what you expected to happen.

Logs //flag is true to start //code above is executed, true is retrieved // then enter "main" section

//i update ld website to set it to false (the client or some part of it sees the update) 2023-10-07 16:48:09,035 - ldclient.util.process_message:142 - DEBUG - Received patch event for /flags/david-ld-test-bool, New version: [5] 2023-10-07 16:48:09,035 - ldclient.util.upsert:152 - DEBUG - Updated david-ld-test-bool in 'features' to version 5

//but when I read the flag again it is still true 2023-10-07 16:48:58,416 - get_ld_flag:180 - DEBUG - LD FLAG EVAL: david-ld-test-bool is True

SDK version launchdarkly-server-sdk 8.1.6

Language version, developer tools python 3.8.10

OS/platform Linux in AWS

Additional context Add any other context about the problem here.

keelerm84 commented 9 months ago

Thank you for bringing this to our attention. I will try to get to this as soon as I can and will post back here once I have some resolution for you.

Tracking internally as sc-220284

keelerm84 commented 9 months ago

I tried using the example you provided, but I wasn't able to duplicate this issue. I am going to include my entire test script below just to make sure we are working from identical code. Can you run this and see if you are experiencing the problem with this script?

In your test, were you running this as a single stand-alone script, or was the code you provided an excerpt from a larger application where you are seeing this behavior?

#!/usr/bin/env python
import ldclient
from ldclient import Context
from ldclient.config import Config
import time

from typing import Any, Optional

sdk_key = "SET ME TO YOUR VALID KEY"
feature_flag_key = "SET ME TO YOUR FAVORITE BOOLEAN FLAG"
context = Context.builder('example-user-key').name("Sandy").build()

def __init_feature_flags_client() -> ldclient.LDClient:
    ldclient.set_config(Config(sdk_key, flush_interval=5 * 60))
    return ldclient.get()

def get_ld_flag(flag_name: str, default: Any, context: Optional[Context] = None) -> Any:
    client = None
    try:
        client = ldclient.get()
    except Exception:
        __init_feature_flags_client()
        client = ldclient.get()

    if context is None:
        context = Context.builder('example-user-key').anonymous(True).build()

    result = client.variation(flag_name, context, default)
    print(f"LD FLAG EVAL: {flag_name} is {result}")
    return result

get_ld_flag(feature_flag_key, False, context)

if __name__ == "__main__":
    # change the value for flag in ld.com interface
    while True:
        time.sleep(1)
        get_ld_flag(feature_flag_key, False, context)
github-actions[bot] commented 8 months ago

This issue is marked as stale because it has been open for 30 days without activity. Remove the stale label or comment, or this will be closed in 7 days.