예제 #1
0
    def __init__(self, **kwargs):
        state = profile.create()
        data = profile.plot_data(state, profile_interval)
        self.states = data.pop("states")
        self.root, self.source = profile.plot_figure(data, **kwargs)

        @without_property_validation
        def cb(attr, old, new):
            with log_errors():
                try:
                    selected = new.indices
                except AttributeError:
                    selected = new["1d"]["indices"]
                try:
                    ind = selected[0]
                except IndexError:
                    return
                data = profile.plot_data(self.states[ind], profile_interval)
                del self.states[:]
                self.states.extend(data.pop("states"))
                update(self.source, data)
                self.source.selected = old

        if BOKEH_VERSION >= "1.0.0":
            self.source.selected.on_change("indices", cb)
        else:
            self.source.on_change("selected", cb)
예제 #2
0
 def trigger_update(self):
     self.state = profile.get_profile(self.log, start=self.start, stop=self.stop)
     data = profile.plot_data(self.state, profile_interval)
     self.states = data.pop("states")
     update(self.source, data)
     times = [t * 1000 for t, _ in self.log]
     counts = list(toolz.pluck("count", toolz.pluck(1, self.log)))
     self.ts_source.data.update({"time": times, "count": counts})
예제 #3
0
 def cb(attr, old, new):
     if changing[0] or len(new) == 0:
         return
     with log_errors():
         data = profile.plot_data(self.states[new[0]], profile_interval)
         del self.states[:]
         self.states.extend(data.pop("states"))
         changing[0] = True  # don't recursively trigger callback
         update(self.source, data)
         self.source.selected.indices = old
         changing[0] = False
예제 #4
0
 def cb(attr, old, new):
     with log_errors():
         try:
             ind = new.indices[0]
         except IndexError:
             return
         data = profile.plot_data(self.states[ind], profile_interval)
         del self.states[:]
         self.states.extend(data.pop("states"))
         update(self.source, data)
         self.source.selected = old
예제 #5
0
    def update(self, state, metadata=None):
        with log_errors():
            self.state = state
            data = profile.plot_data(self.state, profile_interval)
            self.states = data.pop("states")
            update(self.source, data)

            if metadata is not None and metadata["counts"]:
                self.task_names = ["All"] + sorted(metadata["keys"])
                self.select.options = self.task_names
                if self.key:
                    ts = metadata["keys"][self.key]
                else:
                    ts = metadata["counts"]
                times, counts = zip(*ts)
                self.ts = {"count": counts, "time": [t * 1000 for t in times]}

                self.ts_source.data.update(self.ts)
예제 #6
0
def test_basic():
    def test_g():
        sleep(0.01)

    def test_h():
        sleep(0.02)

    def test_f():
        for i in range(100):
            test_g()
            test_h()

    thread = threading.Thread(target=test_f)
    thread.daemon = True
    thread.start()

    state = create()

    for i in range(100):
        sleep(0.02)
        frame = sys._current_frames()[thread.ident]
        process(frame, None, state)

    assert state["count"] == 100
    d = state
    while len(d["children"]) == 1:
        d = first(d["children"].values())

    assert d["count"] == 100
    assert "test_f" in str(d["description"])
    g = [
        c for c in d["children"].values() if "test_g" in str(c["description"])
    ][0]
    h = [
        c for c in d["children"].values() if "test_h" in str(c["description"])
    ][0]

    assert g["count"] < h["count"]
    assert 95 < g["count"] + h["count"] <= 100

    pd = plot_data(state)
    assert len(set(map(len, pd.values()))) == 1  # all same length
    assert len(set(pd["color"])) > 1  # different colors
예제 #7
0
 def cb(attr, old, new):
     if changing[0]:
         return
     with log_errors():
         if isinstance(new, list):  # bokeh >= 1.0
             selected = new
         else:
             selected = new["1d"]["indices"]
         try:
             ind = selected[0]
         except IndexError:
             return
         data = profile.plot_data(self.states[ind], profile_interval)
         del self.states[:]
         self.states.extend(data.pop("states"))
         changing[0] = True  # don't recursively trigger callback
         update(self.source, data)
         if isinstance(new, list):  # bokeh >= 1.0
             self.source.selected.indices = old
         else:
             self.source.selected = old
         changing[0] = False
예제 #8
0
 def update(self, state):
     with log_errors():
         self.state = state
         data = profile.plot_data(self.state, profile_interval)
         self.states = data.pop("states")
         update(self.source, data)
예제 #9
0
    def __init__(self, server, doc=None, **kwargs):
        if doc is not None:
            self.doc = weakref.ref(doc)
        self.server = server
        self.log = self.server.io_loop.profile
        self.start = None
        self.stop = None
        self.ts = {"count": [], "time": []}
        self.state = profile.get_profile(self.log)
        data = profile.plot_data(self.state, profile_interval)
        self.states = data.pop("states")
        self.profile_plot, self.source = profile.plot_figure(data, **kwargs)

        changing = [False]  # avoid repeated changes from within callback

        @without_property_validation
        def cb(attr, old, new):
            if changing[0]:
                return
            with log_errors():
                if isinstance(new, list):  # bokeh >= 1.0
                    selected = new
                else:
                    selected = new["1d"]["indices"]
                try:
                    ind = selected[0]
                except IndexError:
                    return
                data = profile.plot_data(self.states[ind], profile_interval)
                del self.states[:]
                self.states.extend(data.pop("states"))
                changing[0] = True  # don't recursively trigger callback
                update(self.source, data)
                if isinstance(new, list):  # bokeh >= 1.0
                    self.source.selected.indices = old
                else:
                    self.source.selected = old
                changing[0] = False

        if BOKEH_VERSION >= "1.0.0":
            self.source.selected.on_change("indices", cb)
        else:
            self.source.on_change("selected", cb)

        self.ts_source = ColumnDataSource({"time": [], "count": []})
        self.ts_plot = figure(
            title="Activity over time",
            height=150,
            x_axis_type="datetime",
            active_drag="xbox_select",
            tools="xpan,xwheel_zoom,xbox_select,reset",
            sizing_mode="stretch_width",
            toolbar_location="above",
        )
        self.ts_plot.line("time", "count", source=self.ts_source)
        self.ts_plot.circle(
            "time", "count", source=self.ts_source, color=None, selection_color="orange"
        )
        self.ts_plot.yaxis.visible = False
        self.ts_plot.grid.visible = False

        def ts_change(attr, old, new):
            with log_errors():
                try:
                    selected = self.ts_source.selected.indices
                except AttributeError:
                    selected = self.ts_source.selected["1d"]["indices"]
                if selected:
                    start = self.ts_source.data["time"][min(selected)] / 1000
                    stop = self.ts_source.data["time"][max(selected)] / 1000
                    self.start, self.stop = min(start, stop), max(start, stop)
                else:
                    self.start = self.stop = None
                self.trigger_update()

        if BOKEH_VERSION >= "1.0.0":
            self.ts_source.selected.on_change("indices", ts_change)
        else:
            self.ts_source.on_change("selected", ts_change)

        self.reset_button = Button(label="Reset", button_type="success")
        self.reset_button.on_click(lambda: self.update(self.state))

        self.update_button = Button(label="Update", button_type="success")
        self.update_button.on_click(self.trigger_update)

        self.root = column(
            row(self.reset_button, self.update_button, sizing_mode="scale_width"),
            self.profile_plot,
            self.ts_plot,
            **kwargs
        )
예제 #10
0
    def __init__(self, server, doc=None, **kwargs):
        if doc is not None:
            self.doc = weakref.ref(doc)
            try:
                self.key = doc.session_context.request.arguments.get("key", None)
            except AttributeError:
                self.key = None
            if isinstance(self.key, list):
                self.key = self.key[0]
            if isinstance(self.key, bytes):
                self.key = self.key.decode()
            self.task_names = ["All", self.key] if self.key else ["All"]
        else:
            self.key = None
            self.task_names = ["All"]

        self.server = server
        self.start = None
        self.stop = None
        self.ts = {"count": [], "time": []}
        self.state = profile.create()
        data = profile.plot_data(self.state, profile_interval)
        self.states = data.pop("states")
        self.profile_plot, self.source = profile.plot_figure(data, **kwargs)

        changing = [False]  # avoid repeated changes from within callback

        @without_property_validation
        def cb(attr, old, new):
            if changing[0] or len(new) == 0:
                return
            with log_errors():
                data = profile.plot_data(self.states[new[0]], profile_interval)
                del self.states[:]
                self.states.extend(data.pop("states"))
                changing[0] = True  # don't recursively trigger callback
                update(self.source, data)
                self.source.selected.indices = old
                changing[0] = False

        self.source.selected.on_change("indices", cb)

        self.ts_source = ColumnDataSource({"time": [], "count": []})
        self.ts_plot = figure(
            title="Activity over time",
            height=150,
            x_axis_type="datetime",
            active_drag="xbox_select",
            tools="xpan,xwheel_zoom,xbox_select,reset",
            sizing_mode="stretch_width",
            toolbar_location="above",
        )
        self.ts_plot.line("time", "count", source=self.ts_source)
        self.ts_plot.circle(
            "time", "count", source=self.ts_source, color=None, selection_color="orange"
        )
        self.ts_plot.yaxis.visible = False
        self.ts_plot.grid.visible = False

        def ts_change(attr, old, new):
            with log_errors():
                selected = self.ts_source.selected.indices
                if selected:
                    start = self.ts_source.data["time"][min(selected)] / 1000
                    stop = self.ts_source.data["time"][max(selected)] / 1000
                    self.start, self.stop = min(start, stop), max(start, stop)
                else:
                    self.start = self.stop = None
                self.trigger_update(update_metadata=False)

        self.ts_source.selected.on_change("indices", ts_change)

        self.reset_button = Button(label="Reset", button_type="success")
        self.reset_button.on_click(lambda: self.update(self.state))

        self.update_button = Button(label="Update", button_type="success")
        self.update_button.on_click(self.trigger_update)

        self.select = Select(value=self.task_names[-1], options=self.task_names)

        def select_cb(attr, old, new):
            if new == "All":
                new = None
            self.key = new
            self.trigger_update(update_metadata=False)

        self.select.on_change("value", select_cb)

        self.root = column(
            row(
                self.select,
                self.reset_button,
                self.update_button,
                sizing_mode="scale_width",
                height=250,
            ),
            self.profile_plot,
            self.ts_plot,
            **kwargs,
        )