# Path: chamber/utils/transaction.py
# def pre_commit(func, using=None):
#     connection = get_connection(using)
# 
#     if connection.in_atomic_block:
#         # Transaction in progress; save for execution on commit.
#         func_hash = hash(func) if isinstance(func, UniquePreCommitCallable) else None
#         if (func_hash is None
#                 or func_hash not in {func_hash for sids, func_hash, func in connection.run_pre_commit}):
#             connection.run_pre_commit.append((set(connection.savepoint_ids), func_hash, func))
# 
#     elif not connection.get_autocommit():
#         raise TransactionManagementError('pre_commit() cannot be used in manual transaction management')
#     else:
#         # No transaction in progress and in autocommit mode; execute immediately.
#         func()
# 
# class UniquePreCommitCallable:
#     """
#     One time callable class that is used for performing on success operations.
#     Handler is callable only once, but data of all calls are stored inside list (kwargs_list).
#     """
# 
#     def __init__(self, **kwargs):
#         self.kwargs_list = (kwargs,)
# 
#     def join(self, callable):
#         """
#         Joins two unique callable.
#         """
#         self.kwargs_list += callable.kwargs_list
# 
#     def _get_unique_id(self):
#         """
#         Callable instance hash is generated from class name and the return value of this method.
#         The method returns None by default, therefore the class init data doesn't have impact.
#         You should implement this method to distinguish callable according to its
#         input data (for example Django model instance)
#         :return:
#         """
#         return None
# 
#     def __hash__(self):
#         return hash((self.__class__, self._get_unique_id()))
# 
#     def _get_kwargs(self):
#         return self.kwargs_list[-1]
# 
#     def __call__(self):
#         self.handle()
# 
#     def handle(self):
#         raise NotImplementedError
# 
# Path: chamber/models/signals.py



from django.core.exceptions import ImproperlyConfigured
from chamber.utils.transaction import pre_commit, UniquePreCommitCallable
from chamber.models.signals import dispatcher_post_save
        these are hidden in args and kwargs.
        """
        if self.can_handle(instance, **kwargs):
            self._handle(instance, **kwargs)

    def _handle(self, instance, **kwargs):
        self.handle(instance, **kwargs)

    def can_handle(self, instance, **kwargs):
        return True

    def handle(self, instance, **kwargs):
        raise NotImplementedError


class PreCommitHandler(BaseHandler):
    """
    Handler class that is used for performing on success operations.
    """

    signal = dispatcher_post_save

    def __init__(self, using=None, *args, **kwargs):
        self.using = using
        super().__init__(*args, **kwargs)

    def _handle(self, instance, **kwargs):
        pre_commit(lambda: self.handle(instance, **kwargs), using=self.using)



# Path: chamber/utils/transaction.py
# def pre_commit(func, using=None):
#     connection = get_connection(using)
# 
#     if connection.in_atomic_block:
#         # Transaction in progress; save for execution on commit.
#         func_hash = hash(func) if isinstance(func, UniquePreCommitCallable) else None
#         if (func_hash is None
#                 or func_hash not in {func_hash for sids, func_hash, func in connection.run_pre_commit}):
#             connection.run_pre_commit.append((set(connection.savepoint_ids), func_hash, func))
# 
#     elif not connection.get_autocommit():
#         raise TransactionManagementError('pre_commit() cannot be used in manual transaction management')
#     else:
#         # No transaction in progress and in autocommit mode; execute immediately.
#         func()
# 
# class UniquePreCommitCallable:
#     """
#     One time callable class that is used for performing on success operations.
#     Handler is callable only once, but data of all calls are stored inside list (kwargs_list).
#     """
# 
#     def __init__(self, **kwargs):
#         self.kwargs_list = (kwargs,)
# 
#     def join(self, callable):
#         """
#         Joins two unique callable.
#         """
#         self.kwargs_list += callable.kwargs_list
# 
#     def _get_unique_id(self):
#         """
#         Callable instance hash is generated from class name and the return value of this method.
#         The method returns None by default, therefore the class init data doesn't have impact.
#         You should implement this method to distinguish callable according to its
#         input data (for example Django model instance)
#         :return:
#         """
#         return None
# 
#     def __hash__(self):
#         return hash((self.__class__, self._get_unique_id()))
# 
#     def _get_kwargs(self):
#         return self.kwargs_list[-1]
# 
#     def __call__(self):
#         self.handle()
# 
#     def handle(self):
#         raise NotImplementedError
# 
# Path: chamber/models/signals.py



# Path: chamber/models/handlers.py
from django.core.exceptions import ImproperlyConfigured
from chamber.utils.transaction import pre_commit, UniquePreCommitCallable
from chamber.models.signals import dispatcher_post_save

        these are hidden in args and kwargs.
        """
        if self.can_handle(instance, **kwargs):
            self._handle(instance, **kwargs)

    def _handle(self, instance, **kwargs):
        self.handle(instance, **kwargs)

    def can_handle(self, instance, **kwargs):
        return True

    def handle(self, instance, **kwargs):
        raise NotImplementedError


class PreCommitHandler(BaseHandler):
    """
    Handler class that is used for performing on success operations.
    """

    signal = dispatcher_post_save

    def __init__(self, using=None, *args, **kwargs):
        self.using = using
        super().__init__(*args, **kwargs)

    def _handle(self, instance, **kwargs):
        pre_commit(lambda: self.handle(instance, **kwargs), using=self.using)



class InstanceOneTimePreCommitHandlerCallable(UniquePreCommitCallable):