Skip to content
This repository was archived by the owner on Jan 29, 2025. It is now read-only.
This repository was archived by the owner on Jan 29, 2025. It is now read-only.

Context leakage when using decorators #71

@partizaans

Description

@partizaans

Issue

We faced a strange problem. Some of the queries inside of some views that are not decorated with the @use_slave were getting routed to the slave db instances.
After a couple of hours spent debugging found the reproduction routine.

Reproduce

Consider:

@use_slave
def v1(request, *args, **kwargs):
    raise Exception('!')
    ...


def v2(request, *args, **kwargs):
    print(Model2.objects.all()) # <--- Routed to the slave
    ...

Decorators are using ReplicationMiddleware but ReplicationMiddleware is not implementing process_exception and if the exception is not handled, the ReplicationMiddleware#process_response and routers.reset() are not called at all. Hence, the _context on the router remains dirty.
So any v2 call that is happening after the v1 raising an exception get routed to the slave instances.

Fix

Just wrapped the django_replicated decorator just like:

def use_replicas(function_based_view):
    def inner(*args, **kwargs):
        from django_replicated.decorators import use_slave
        from django_replicated.utils import routers

        try:
            return use_slave(function_based_view)(*args, **kwargs)
        except Exception as e:
            routers.reset()
            raise e

    return inner

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions