Example #1
0
 def test_kill_removes_trace(self):
     from greenlet import gettrace
     hub = get_hub()
     hub.start_periodic_monitoring_thread()
     self.assertIsNotNone(gettrace())
     hub.periodic_monitoring_thread.kill()
     self.assertIsNone(gettrace())
Example #2
0
 def test_kill_removes_trace(self):
     from greenlet import gettrace
     hub = get_hub()
     hub.start_periodic_monitoring_thread()
     self.assertIsNotNone(gettrace())
     hub.periodic_monitoring_thread.kill()
     self.assertIsNone(gettrace())
Example #3
0
 def tearDown(self):
     monitor.start_new_thread = self._orig_start_new_thread
     monitor.thread_sleep = self._orig_thread_sleep
     prev = self.pmt.previous_trace_function
     self.pmt.kill()
     assert gettrace() is prev, (gettrace(), prev)
     settrace(None)
     super(_AbstractTestPeriodicMonitoringThread, self).tearDown()
Example #4
0
 def tearDown(self):
     monitor.start_new_thread = self._orig_start_new_thread
     monitor.thread_sleep = self._orig_thread_sleep
     prev = self.pmt._greenlet_tracer.previous_trace_function
     self.pmt.kill()
     assert gettrace() is prev, (gettrace(), prev)
     settrace(None)
     super(_AbstractTestPeriodicMonitoringThread, self).tearDown()
Example #5
0
    def test_nested(self):
        from greenlet import gettrace
        with util.assert_switches() as outer:
            self.assertEqual(gettrace(), outer.tracer)
            self.assertIsNotNone(outer.tracer.active_greenlet)

            with util.assert_switches() as inner:
                self.assertEqual(gettrace(), inner.tracer)
                self.assertEqual(inner.tracer.previous_trace_function, outer.tracer)

                inner.tracer('switch', (self, self))

                self.assertIs(self, inner.tracer.active_greenlet)
                self.assertIs(self, outer.tracer.active_greenlet)

            self.assertEqual(gettrace(), outer.tracer)
Example #6
0
    def test_previous_trace(self):
        self.pmt.kill()
        self.assertIsNone(gettrace())

        called = []
        def f(*args):
            called.append(args)

        settrace(f)

        self.pmt = monitor.PeriodicMonitoringThread(self.hub)
        self.assertEqual(gettrace(), self.pmt._greenlet_tracer)
        self.assertIs(self.pmt._greenlet_tracer.previous_trace_function, f)

        self.pmt._greenlet_tracer('event', ('args',))

        self.assertEqual([('event', ('args',))], called)
Example #7
0
    def test_nested(self):
        from greenlet import gettrace
        with util.assert_switches() as outer:
            self.assertEqual(gettrace(), outer.tracer)
            self.assertIsNotNone(outer.tracer.active_greenlet)

            with util.assert_switches() as inner:
                self.assertEqual(gettrace(), inner.tracer)
                self.assertEqual(inner.tracer.previous_trace_function,
                                 outer.tracer)

                inner.tracer('switch', (self, self))

                self.assertIs(self, inner.tracer.active_greenlet)
                self.assertIs(self, outer.tracer.active_greenlet)

            self.assertEqual(gettrace(), outer.tracer)
Example #8
0
    def test_previous_trace(self):
        self.pmt.kill()
        self.assertIsNone(gettrace())

        called = []
        def f(*args):
            called.append(args)

        settrace(f)

        self.pmt = monitor.PeriodicMonitoringThread(self.hub)
        self.assertEqual(gettrace(), self.pmt.greenlet_trace)
        self.assertIs(self.pmt.previous_trace_function, f)

        self.pmt.greenlet_trace('event', 'args')

        self.assertEqual([('event', 'args')], called)
Example #9
0
    def test_hub_wref(self):
        self.assertIs(self.hub, self.pmt.hub)
        del self.hub

        gc.collect()
        self.assertIsNone(self.pmt.hub)

        # And it killed itself.
        self.assertFalse(self.pmt.should_run)
        self.assertIsNone(gettrace())
Example #10
0
    def test_hub_wref(self):
        self.assertIs(self.hub, self.pmt.hub)
        del self.hub

        gc.collect()
        self.assertIsNone(self.pmt.hub)

        # And it killed itself.
        self.assertFalse(self.pmt.should_run)
        self.assertIsNone(gettrace())
Example #11
0
    def test_b_exception_disables_tracing(self):
        main = greenlet.getcurrent()
        def dummy():
            main.switch()
        g = greenlet.greenlet(dummy)
        g.switch()
        with GreenletTracer(error_on_trace=True) as actions:
            self.assertRaises(SomeError, g.switch)
            self.assertEqual(greenlet.gettrace(), None)

        self.assertEqual(actions, [
            ('switch', (main, g)),
        ])
Example #12
0
 def test_exception_disables_tracing(self):
     main = greenlet.getcurrent()
     actions = []
     def trace(*args):
         actions.append(args)
         raise SomeError()
     def dummy():
         main.switch()
     g = greenlet.greenlet(dummy)
     g.switch()
     oldtrace = greenlet.settrace(trace)
     try:
         self.assertRaises(SomeError, g.switch)
         self.assertEqual(greenlet.gettrace(), None)
     finally:
         greenlet.settrace(oldtrace)
     self.assertEqual(actions, [
         ('switch', (main, g)),
     ])
Example #13
0
    def __init__(self, collector, sample_interval=0.1):
        self.collector = collector
        self.sample_interval = sample_interval
        self.last_timestamp = time.time()

        # Save the old frame to have proper stack reporting. If the following
        # code is executed:
        #
        #   slow() # At this point a new sample is *not* needed
        #   f2()   # When this calls happens a new sample is needed, *because
        #          # of the previous function*
        #
        # The above gets worse because a context switch can happen after the
        # call to slow, if this is not taken into account a completely wrong
        # stack trace will be reported.
        self.old_frame = None

        self.previous_callback = greenlet.gettrace()
        greenlet.settrace(self._greenlet_profiler)  # pylint: disable=c-extension-no-member
        sys.setprofile(self._thread_profiler)
Example #14
0
def install_switch_log():
    # Do not overwrite the previous installed tracing function, this could be
    # another profiling tool, and if the callback is overwriten the tool would
    # not work as expected (e.g. a trace sampler)
    previous_callback = greenlet.gettrace()

    def log_every_switch(event: str, args: Any) -> None:
        if event == "switch":
            origin, target = args

            # Collecting the complete stack frame because the top-level
            # function will be a greenlet, and the bottom function may be an
            # external library. To understand what is going on the application
            # code, the whole stack is necessary.
            frame = sys._getframe(0)
            callstack = collect_frames(frame)

            # Using `print` because logging will not work here, the logger may
            # not be properly initialized on a fresh greenlet and will try to
            # use a nullable variable.
            print(
                json.dumps({
                    "event": "Switching",
                    "origin": str(origin),
                    "target": str(target),
                    "target_callstack": callstack,
                    "time": datetime.utcnow().isoformat(),
                }))

        if previous_callback is not None:
            return previous_callback(event, args)

        return None

    greenlet.settrace(log_every_switch)

    return previous_callback
Example #15
0
 def greenlet_settrace(self):
     'Check if any greenlet trace function is registered.'
     return bool(greenlet.gettrace())
Example #16
0
 def greenlet_settrace(self):
     'Check if any greenlet trace function is registered.'
     return bool(greenlet.gettrace())
Example #17
0
    def execute(self):
        self.log.debug('Executing {}'.format(self.graph))

        # Initialize graph
        if self.graph.state == ComponentState.NOT_INITIALIZED:
            self.graph.initialize()
            self.graph.state = ComponentState.INITIALIZED

        # Enable tracing
        old_trace = greenlet.gettrace()
        if self.DETECT_BLOCKING:
            greenlet.settrace(self._blocking_greenlet_detector)

        self._running = True
        try:
            all_components = set()
            self._graph_lookup = {}
            for component, graph in self.graph.get_all_components(
                    include_graphs=True):
                self._graph_lookup[component] = graph
                all_components.add(component)
                component.executor = self

                # Component should always be in a INITIALIZED state when first
                # running!
                if component.state != ComponentState.INITIALIZED:
                    raise exc.ComponentStateError(
                        component,
                        'state is {}, but expected INITIALIZED'.format(
                            component.state))

                component.state = ComponentState.ACTIVE

            self.log.debug('Components in {}: {}'.format(
                self.graph, ', '.join(map(str, all_components))))

            self._recv_queues = collections.defaultdict(queue.Queue)
            self._coroutines = dict([
                (
                    gevent.spawn(
                        self._create_component_runner(comp),
                        None,  # in_queues
                        None),  # out_queues
                    comp) for comp in filter(
                        lambda c: not isinstance(c, Graph), all_components)
            ])

            last_exception = None

            def thread_error_handler(coroutine):
                """
                Handles component coroutine exceptions that get raised.
                This should terminate execution of all other coroutines.
                """
                last_exception = coroutine.exception

                component = self._coroutines[coroutine]
                self.log.error('Component "{}" failed with {}: {}'.format(
                    component.name, coroutine.exception.__class__.__name__,
                    coroutine.exception.message))

                for c in all_components:
                    if c.is_alive():
                        c.terminate(ex=last_exception)

            # Wire up error handler (so that exceptions aren't swallowed)
            for coroutine in self._coroutines.keys():
                coroutine.link_exception(thread_error_handler)

            # Wait for all coroutines to terminate
            gevent.wait(self._coroutines.keys())

            self.graph.terminate(ex=last_exception)
            self._final_checks()
            self._reset_components()

            self.log.debug('Finished graph execution')

        finally:
            self._running = False
            if self.DETECT_BLOCKING:
                # Unset tracer
                greenlet.settrace(old_trace)
Example #18
0
 def test_constructor(self):
     self.assertEqual(0xDEADBEEF, self.pmt.monitor_thread_ident)
     self.assertEqual(gettrace(), self.pmt._greenlet_tracer)
Example #19
0
    def execute(self):
        self.log.debug("Executing {}".format(self.graph))

        # Initialize graph
        if self.graph.state == ComponentState.NOT_INITIALIZED:
            self.graph.initialize()
            self.graph.state = ComponentState.INITIALIZED

        # Enable tracing
        old_trace = greenlet.gettrace()
        if self.DETECT_BLOCKING:
            greenlet.settrace(self._blocking_greenlet_detector)

        self._running = True
        try:
            all_components = set()
            self._graph_lookup = {}
            for component, graph in self.graph.get_all_components(include_graphs=True):
                self._graph_lookup[component] = graph
                all_components.add(component)
                component.executor = self

                # Component should always be in a INITIALIZED state when first
                # running!
                if component.state != ComponentState.INITIALIZED:
                    raise exc.ComponentStateError(
                        component, "state is {}, but expected INITIALIZED".format(component.state)
                    )

                component.state = ComponentState.ACTIVE

            self.log.debug("Components in {}: {}".format(self.graph, ", ".join(map(str, all_components))))

            self._recv_queues = collections.defaultdict(queue.Queue)
            self._coroutines = dict(
                [
                    (gevent.spawn(self._create_component_runner(comp), None, None), comp)  # in_queues  # out_queues
                    for comp in filter(lambda c: not isinstance(c, Graph), all_components)
                ]
            )

            last_exception = None

            def thread_error_handler(coroutine):
                """
                Handles component coroutine exceptions that get raised.
                This should terminate execution of all other coroutines.
                """
                last_exception = coroutine.exception

                component = self._coroutines[coroutine]
                self.log.error(
                    'Component "{}" failed with {}: {}'.format(
                        component.name, coroutine.exception.__class__.__name__, coroutine.exception.message
                    )
                )

                for c in all_components:
                    if c.is_alive():
                        c.terminate(ex=last_exception)

            # Wire up error handler (so that exceptions aren't swallowed)
            for coroutine in self._coroutines.keys():
                coroutine.link_exception(thread_error_handler)

            # Wait for all coroutines to terminate
            gevent.wait(self._coroutines.keys())

            self.graph.terminate(ex=last_exception)
            self._final_checks()
            self._reset_components()

            self.log.debug("Finished graph execution")

        finally:
            self._running = False
            if self.DETECT_BLOCKING:
                # Unset tracer
                greenlet.settrace(old_trace)
Example #20
0
 def test_constructor(self):
     self.assertEqual(0xDEADBEEF, self.pmt.monitor_thread_ident)
     self.assertEqual(gettrace(), self.pmt.greenlet_trace)
Example #21
0
def _check():
    # 任务监控
    greenlet.settrace(lambda: 2)
    greenlet.gettrace()