<commit_before>from contextlib import contextmanager
from django.db import models

from elasticsearch_dsl.connections import connections

from django_elasticsearch_dsl.registries import registry
from django_elasticsearch_dsl.signals import RealTimeSignalProcessor

from ..tasks import (
    search_instance_save, search_instance_pre_delete,
    search_instance_delete
)


@contextmanager
def realtime_search():
    signal_processor = CelerySignalProcessor(connections)
    signal_processor.setup()
    yield
    signal_processor.teardown()


class CelerySignalProcessor(RealTimeSignalProcessor):
    def setup(self):
        for doc in registry.get_documents():
            if getattr(doc, 'special_signals', False):
                continue
            model = doc._doc_type.model
            models.signals.post_save.connect(self.handle_save, sender=model)
            models.signals.post_delete.connect(self.handle_delete, sender=model)

            models.signals.m2m_changed.connect(self.handle_m2m_changed, sender=model)
            models.signals.pre_delete.connect(self.handle_pre_delete, sender=model)

    def teardown(self):
        # Listen to all model saves.
        for doc in registry.get_documents():
            if getattr(doc, 'special_signals', False):
                continue
            model = doc._doc_type.model
            models.signals.post_save.disconnect(self.handle_save, sender=model)
            models.signals.post_delete.disconnect(self.handle_delete, sender=model)
            models.signals.m2m_changed.disconnect(self.handle_m2m_changed, sender=model)
            models.signals.pre_delete.disconnect(self.handle_pre_delete, sender=model)

    def handle_save(self, sender, instance, **kwargs):
        """Handle save.

        Given an individual model instance, update the object in the index.
        Update the related objects either.
        """
        search_instance_save.delay(instance._meta.label_lower, instance.pk)

    def handle_pre_delete(self, sender, instance, **kwargs):
        """Handle removing of instance object from related models instance.
        We need to do this before the real delete otherwise the relation
        doesn't exists anymore and we can't get the related models instance.
        """
        search_instance_pre_delete.delay(instance._meta.label_lower, instance.pk)

    def handle_delete(self, sender, instance, **kwargs):
        """Handle delete.

        Given an individual model instance, delete the object from index.
        """
        search_instance_delete.delay(instance._meta.label_lower, instance.pk)<commit_msg>Trigger search indexing after transaction commit<commit_after>from contextlib import contextmanager
from django.db import models
from django.db import transaction

from elasticsearch_dsl.connections import connections

from django_elasticsearch_dsl.registries import registry
from django_elasticsearch_dsl.signals import RealTimeSignalProcessor

from ..tasks import (
    search_instance_save, search_instance_pre_delete,
    search_instance_delete
)


@contextmanager
def realtime_search():
    signal_processor = CelerySignalProcessor(connections)
    signal_processor.setup()
    yield
    signal_processor.teardown()


class CelerySignalProcessor(RealTimeSignalProcessor):
    def setup(self):
        for doc in registry.get_documents():
            if getattr(doc, 'special_signals', False):
                continue
            model = doc._doc_type.model
            models.signals.post_save.connect(self.handle_save, sender=model)
            models.signals.post_delete.connect(self.handle_delete, sender=model)

            models.signals.m2m_changed.connect(self.handle_m2m_changed, sender=model)
            models.signals.pre_delete.connect(self.handle_pre_delete, sender=model)

    def teardown(self):
        # Listen to all model saves.
        for doc in registry.get_documents():
            if getattr(doc, 'special_signals', False):
                continue
            model = doc._doc_type.model
            models.signals.post_save.disconnect(self.handle_save, sender=model)
            models.signals.post_delete.disconnect(self.handle_delete, sender=model)
            models.signals.m2m_changed.disconnect(self.handle_m2m_changed, sender=model)
            models.signals.pre_delete.disconnect(self.handle_pre_delete, sender=model)

    def handle_save(self, sender, instance, **kwargs):
        """Handle save.

        Given an individual model instance, update the object in the index.
        Update the related objects either.
        """
        transaction.on_commit(lambda: search_instance_save.delay(instance._meta.label_lower, instance.pk))

    def handle_pre_delete(self, sender, instance, **kwargs):
        """Handle removing of instance object from related models instance.
        We need to do this before the real delete otherwise the relation
        doesn't exists anymore and we can't get the related models instance.
        """
        transaction.on_commit(lambda: search_instance_pre_delete.delay(instance._meta.label_lower, instance.pk))

    def handle_delete(self, sender, instance, **kwargs):
        """Handle delete.

        Given an individual model instance, delete the object from index.
        """
        transaction.on_commit(lambda: search_instance_delete.delay(instance._meta.label_lower, instance.pk))
{'fraction_non_alphanumeric': 0.07791000371885459, 'fraction_numerical': 0.0014875418371141688, 'mean_word_length': 3.3484236054971706, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2636472', 'n_tokens_mistral': 1442, 'n_tokens_neox': 1409, 'n_words': 343}