Pass `loglevel` down through `.ui` graphics tasks

Add `loglevel` propagation to UI graphics tasks and sampler stream
opens to enable proper console logging in chart update loops. This
ensures the graphics and FSP subsystems receive the same loglevel
as their parent and/or sibling UI-actor tasks.

Deats,
- add `loglevel` param to `graphics_update_loop()` and
  `increment_history_view()` with default `'warning'`.
- pass `loglevel` to `open_sample_stream()` calls in both fns.
- use `partial()` to pass `loglevel` through to `nurse.start_soon()`
  calls in `display_symbol_data()` and `graphics_update_loop()`.

Also logging, doc-strs, and code-style tweaks,
- change `print()` -> `log.debug()` for hidden-chart and
  interaction-pause msgs in graphics loop.
- change `log.info()` -> `log.debug()` for resize events in
  `GodWidget` and `MainWindow`.
- add multiline style to resize log msg in `GodWidget`.
- add docstring to `MainWindow.on_focus_change()`.
- moar union type annot adjustments.
- switch to explicit kwarg `period_s=` for `open_sample_stream()`
  in `increment_history_view()`.
- multiline style for `names` list in `open_fsp_actor_cluster()`.
- change `count=2` -> `count=len(names)` in
  `open_fsp_actor_cluster()`.
- add TODO about using `.experimental` for cluster import (once that
  get's patched into upstream `tractor`).
- multiline style for `or` in `FspAdmin.start_engine_task()`.
- comment-out unused `brokernames` in `ui.cli.chart()`.
- add commented breakpoint in `ui.cli.chart()`.
- fix docstring style in `OrderMode.on_submit()`.

(this commit msg was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
Gud Boi 2026-02-12 19:24:44 -05:00
parent f2f696d341
commit ed58ae139f
6 changed files with 62 additions and 25 deletions

View File

@ -21,6 +21,7 @@ this module ties together quote and computational (fsp) streams with
graphics update methods via our custom ``pyqtgraph`` charting api. graphics update methods via our custom ``pyqtgraph`` charting api.
''' '''
from functools import partial
import itertools import itertools
from math import floor from math import floor
import time import time
@ -208,6 +209,7 @@ class DisplayState(Struct):
async def increment_history_view( async def increment_history_view(
# min_istream: tractor.MsgStream, # min_istream: tractor.MsgStream,
ds: DisplayState, ds: DisplayState,
loglevel: str = 'warning',
): ):
hist_chart: ChartPlotWidget = ds.hist_chart hist_chart: ChartPlotWidget = ds.hist_chart
hist_viz: Viz = ds.hist_viz hist_viz: Viz = ds.hist_viz
@ -229,7 +231,10 @@ async def increment_history_view(
hist_viz.reset_graphics() hist_viz.reset_graphics()
# hist_viz.update_graphics(force_redraw=True) # hist_viz.update_graphics(force_redraw=True)
async with open_sample_stream(1.) as min_istream: async with open_sample_stream(
period_s=1.,
loglevel=loglevel,
) as min_istream:
async for msg in min_istream: async for msg in min_istream:
profiler = Profiler( profiler = Profiler(
@ -310,7 +315,6 @@ async def increment_history_view(
async def graphics_update_loop( async def graphics_update_loop(
dss: dict[str, DisplayState], dss: dict[str, DisplayState],
nurse: trio.Nursery, nurse: trio.Nursery,
godwidget: GodWidget, godwidget: GodWidget,
@ -319,6 +323,7 @@ async def graphics_update_loop(
pis: dict[str, list[pgo.PlotItem, pgo.PlotItem]] = {}, pis: dict[str, list[pgo.PlotItem, pgo.PlotItem]] = {},
vlm_charts: dict[str, ChartPlotWidget] = {}, vlm_charts: dict[str, ChartPlotWidget] = {},
loglevel: str = 'warning',
) -> None: ) -> None:
''' '''
@ -462,9 +467,12 @@ async def graphics_update_loop(
# }) # })
nurse.start_soon( nurse.start_soon(
partial(
increment_history_view, increment_history_view,
# min_istream, # min_istream,
ds, ds=ds,
loglevel=loglevel,
),
) )
await trio.sleep(0) await trio.sleep(0)
@ -511,14 +519,19 @@ async def graphics_update_loop(
fast_chart.linked.isHidden() fast_chart.linked.isHidden()
or not rt_pi.isVisible() or not rt_pi.isVisible()
): ):
print(f'{fqme} skipping update for HIDDEN CHART') log.debug(
f'{fqme} skipping update for HIDDEN CHART'
)
fast_chart.pause_all_feeds() fast_chart.pause_all_feeds()
continue continue
ic = fast_chart.view._in_interact ic = fast_chart.view._in_interact
if ic: if ic:
fast_chart.pause_all_feeds() fast_chart.pause_all_feeds()
print(f'{fqme} PAUSING DURING INTERACTION') log.debug(
f'Pausing chart updaates during interaction\n'
f'fqme: {fqme!r}'
)
await ic.wait() await ic.wait()
fast_chart.resume_all_feeds() fast_chart.resume_all_feeds()
@ -1591,15 +1604,18 @@ async def display_symbol_data(
# start update loop task # start update loop task
dss: dict[str, DisplayState] = {} dss: dict[str, DisplayState] = {}
ln.start_soon( ln.start_soon(
partial(
graphics_update_loop, graphics_update_loop,
dss, dss=dss,
ln, nurse=ln,
godwidget, godwidget=godwidget,
feed, feed=feed,
# min_istream, # min_istream,
pis, pis=pis,
vlm_charts, vlm_charts=vlm_charts,
loglevel=loglevel,
)
) )
# boot order-mode # boot order-mode

View File

@ -183,13 +183,17 @@ async def open_fsp_sidepane(
@acm @acm
async def open_fsp_actor_cluster( async def open_fsp_actor_cluster(
names: list[str] = ['fsp_0', 'fsp_1'], names: list[str] = [
'fsp_0',
'fsp_1',
],
) -> AsyncGenerator[ ) -> AsyncGenerator[
int, int,
dict[str, tractor.Portal] dict[str, tractor.Portal]
]: ]:
# TODO! change to .experimental!
from tractor._clustering import open_actor_cluster from tractor._clustering import open_actor_cluster
# profiler = Profiler( # profiler = Profiler(
@ -197,7 +201,7 @@ async def open_fsp_actor_cluster(
# disabled=False # disabled=False
# ) # )
async with open_actor_cluster( async with open_actor_cluster(
count=2, count=len(names),
names=names, names=names,
modules=['piker.fsp._engine'], modules=['piker.fsp._engine'],
@ -497,7 +501,8 @@ class FspAdmin:
portal: tractor.Portal = ( portal: tractor.Portal = (
self.cluster.get(worker_name) self.cluster.get(worker_name)
or self.rr_next_portal() or
self.rr_next_portal()
) )
# TODO: this should probably be turned into a # TODO: this should probably be turned into a

View File

@ -300,7 +300,10 @@ class GodWidget(QWidget):
getattr(widget, 'on_resize') getattr(widget, 'on_resize')
self._widgets[widget.mode_name] = widget self._widgets[widget.mode_name] = widget
def on_win_resize(self, event: QtCore.QEvent) -> None: def on_win_resize(
self,
event: QtCore.QEvent,
) -> None:
''' '''
Top level god widget handler from window (the real yaweh) resize Top level god widget handler from window (the real yaweh) resize
events such that any registered widgets which wish to be events such that any registered widgets which wish to be
@ -315,7 +318,10 @@ class GodWidget(QWidget):
self._resizing = True self._resizing = True
log.info('God widget resize') log.debug(
f'God widget resize\n'
f'{event}\n'
)
for name, widget in self._widgets.items(): for name, widget in self._widgets.items():
widget.on_resize() widget.on_resize()

View File

@ -255,8 +255,16 @@ class MainWindow(QMainWindow):
current: QWidget, current: QWidget,
) -> None: ) -> None:
'''
Focus handler.
log.info(f'widget focus changed from {last} -> {current}') For now updates the "current mode" name.
'''
log.debug(
f'widget focus changed from,\n'
f'{last} -> {current}'
)
if current is not None: if current is not None:
# cursor left window? # cursor left window?

View File

@ -177,7 +177,7 @@ def chart(
return return
# global opts # global opts
brokernames = config['brokers'] # brokernames: list[str] = config['brokers']
brokermods = config['brokermods'] brokermods = config['brokermods']
assert brokermods assert brokermods
tractorloglevel = config['tractorloglevel'] tractorloglevel = config['tractorloglevel']
@ -216,6 +216,7 @@ def chart(
layers['tcp']['port'], layers['tcp']['port'],
)) ))
# breakpoint()
from tractor.devx import maybe_open_crash_handler from tractor.devx import maybe_open_crash_handler
pdb: bool = config['pdb'] pdb: bool = config['pdb']
with maybe_open_crash_handler(pdb=pdb): with maybe_open_crash_handler(pdb=pdb):

View File

@ -519,7 +519,8 @@ class OrderMode:
''' '''
Order submitted status event handler. Order submitted status event handler.
Commit the order line and registered order uuid, store ack time stamp. Commit the order line and registered order uuid, store ack
time stamp.
''' '''
lines = self.lines.commit_line(uuid) lines = self.lines.commit_line(uuid)