microsoftgraph / microsoftgraph/msgraph-sdk-python

InMemoryBackingStore infinite loop

Abierto
#954 0 comentarios 1 reacción 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

area:backing-store priority:p1 type:bug
Lenguaje dominante
Python
Estrellas
630
Forks
96
Merge medio
15 h 20 min
PR fusionados (30 d)
3

Descripción

Describe the bug

The InMemoryBackingStore class is experiencing an infinite loop when setting values. This occurs because the set method subscribes a lambda function that calls set again, which in turn triggers the subscription callback, causing set to be called repeatedly.

        if isinstance(value, list):
            # if its a collection, subscribe to the collection's item BackingStores and use
            # the events to flag the collection property is "dirty"
            for item in value:
                if isinstance(item, BackedModel) and item.backing_store:
                    item.backing_store.is_initialization_completed = True
                    item.backing_store.subscribe(
                        lambda prop_key, old_val, new_val: self.set(key, value)
                    )

        self.__store[key] = value_to_add
        for sub in list(self.__subscriptions):
            self.__subscriptions[sub](key, old_value, value_to_add)

Because you're invoking the subscription which is calling set which is invoking the subscription.

Expected behavior

The set method should store the value and notify subscribers without causing an infinite loop.

How to reproduce
  1. Create an instance of InMemoryBackingStore.
  2. Set a value that is a BackedModel or a list containing BackedModel instances.
  3. The set method subscribes a lambda function that calls set again.
  4. The subscription callback is triggered, causing set to be called repeatedly.
SDK Version

No response

Latest version known to work for scenario above?

No response

Known Workarounds

Awful, but until an update, unsubscribing and re-subscribing around problematic code.

subscription_ids = []

# Collect all backing stores and sub ids as to not modify while iterating
for role in app.app_roles:
    if isinstance(role, BackedModel) and role.backing_store:
        for (
            sub_id,
            callback,
        ) in role.backing_store._InMemoryBackingStore__subscriptions.items():
            if callback.__name__ == "<lambda>":
                subscription_ids.append((role.backing_store, sub_id))

# Unsubscribe lambdas...
for backing_store, sub_id in subscription_ids:
    backing_store.unsubscribe(sub_id)

# Problematic code
for role in app.app_roles:
    if role.is_enabled != enable:
        role.is_enabled = enable

# Resubscribe lambdas...
for backing_store, sub_id in subscription_ids:
    backing_store.subscribe(
        lambda prop_key, old_val, new_val: role.backing_store.set(
            prop_key, new_val
        ),
        sub_id,
    )
Debug output
Click to expand log ```
</details>


### Configuration

_No response_

### Other information

_No response_

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza localizando la clase InMemoryBackingStore e inspeccionando su método set, especialmente la suscripción añadida para valores BackedModel y listas. Reproduce el problema con un BackedModel o una lista de instancias de BackedModel y sigue las notificaciones a los suscriptores. Se considera terminado cuando establecer el valor lo almacena y notifica a los suscriptores sin invocar set de forma recursiva ni entrar en un bucle infinito.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
backend
Tipo de issue
Error
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Estancado
Claridad
Bien especificado
Aptitud para principiantes
45/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.