# Path: charms/reactive/trace.py
# def tracer():
#     global _tracer
#     return _tracer


import importlib
import os
import sys
import errno
import subprocess
from itertools import chain
from functools import partial
from charmhelpers.core import hookenv
from charmhelpers.core import unitdata
from charms.reactive.trace import tracer
      handlers are re-invoked for every hook and action.  There are
      :doc:`decorators <charms.reactive.decorators>` and
      :doc:`helpers <charms.reactive.helpers>`
      to prevent unnecessary reinvocations, such as
      :func:`~charms.reactive.decorators.only_once`.
    """
    FlagWatch.reset()

    def _test(to_test):
        return list(filter(lambda h: h.test(), to_test))

    def _invoke(to_invoke):
        while to_invoke:
            unitdata.kv().set('reactive.dispatch.removed_state', False)
            for handler in list(to_invoke):
                to_invoke.remove(handler)
                hookenv.log('Invoking reactive handler: %s' % handler.id(), level=hookenv.INFO)
                handler.invoke()
                if unitdata.kv().get('reactive.dispatch.removed_state'):
                    # re-test remaining handlers
                    to_invoke = _test(to_invoke)
                    break
        FlagWatch.commit()

    tracer().start_dispatch()

    # When in restricted context, only run hooks for that context.
    if restricted:
        unitdata.kv().set('reactive.dispatch.phase', 'restricted')
        hook_handlers = _test(Handler.get_handlers())

# Path: charms/reactive/trace.py
# def tracer():
#     global _tracer
#     return _tracer


# Path: charms/reactive/bus.py
import importlib
import os
import sys
import errno
import subprocess
from itertools import chain
from functools import partial
from charmhelpers.core import hookenv
from charmhelpers.core import unitdata
from charms.reactive.trace import tracer

      handlers are re-invoked for every hook and action.  There are
      :doc:`decorators <charms.reactive.decorators>` and
      :doc:`helpers <charms.reactive.helpers>`
      to prevent unnecessary reinvocations, such as
      :func:`~charms.reactive.decorators.only_once`.
    """
    FlagWatch.reset()

    def _test(to_test):
        return list(filter(lambda h: h.test(), to_test))

    def _invoke(to_invoke):
        while to_invoke:
            unitdata.kv().set('reactive.dispatch.removed_state', False)
            for handler in list(to_invoke):
                to_invoke.remove(handler)
                hookenv.log('Invoking reactive handler: %s' % handler.id(), level=hookenv.INFO)
                handler.invoke()
                if unitdata.kv().get('reactive.dispatch.removed_state'):
                    # re-test remaining handlers
                    to_invoke = _test(to_invoke)
                    break
        FlagWatch.commit()

    tracer().start_dispatch()

    # When in restricted context, only run hooks for that context.
    if restricted:
        unitdata.kv().set('reactive.dispatch.phase', 'restricted')
        hook_handlers = _test(Handler.get_handlers())

        tracer().start_dispatch_phase('restricted', hook_handlers)