master,gui: basic log support

This commit is contained in:
Sebastien Bourdeauducq 2015-07-22 05:13:50 +08:00
parent e247fb5415
commit 8402f1cdcd
5 changed files with 79 additions and 7 deletions

View File

@ -105,6 +105,9 @@ def main():
atexit.register(lambda: loop.run_until_complete(d_schedule.sub_close())) atexit.register(lambda: loop.run_until_complete(d_schedule.sub_close()))
d_log = LogDock() d_log = LogDock()
loop.run_until_complete(d_log.sub_connect(
args.server, args.port_notify))
atexit.register(lambda: loop.run_until_complete(d_log.sub_close()))
area.addDock(d_log, "bottom") area.addDock(d_log, "bottom")
area.addDock(d_schedule, "above", d_log) area.addDock(d_schedule, "above", d_log)

View File

@ -30,14 +30,21 @@ def get_argparser():
return parser return parser
class Log:
def __init__(self, depth):
self.depth = depth
self.data = Notifier([])
def log(self, rid, message):
if len(self.data.read) >= self.depth:
del self.data[0]
self.data.append((rid, message))
log.worker_pass_rid = True
def main(): def main():
args = get_argparser().parse_args() args = get_argparser().parse_args()
init_logger(args) init_logger(args)
ddb = FlatFileDB("ddb.pyon")
pdb = FlatFileDB("pdb.pyon")
rtr = Notifier(dict())
if os.name == "nt": if os.name == "nt":
loop = asyncio.ProactorEventLoop() loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop) asyncio.set_event_loop(loop)
@ -45,11 +52,17 @@ def main():
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
atexit.register(lambda: loop.close()) atexit.register(lambda: loop.close())
ddb = FlatFileDB("ddb.pyon")
pdb = FlatFileDB("pdb.pyon")
rtr = Notifier(dict())
log = Log(1000)
worker_handlers = { worker_handlers = {
"get_device": ddb.get, "get_device": ddb.get,
"get_parameter": pdb.get, "get_parameter": pdb.get,
"set_parameter": pdb.set, "set_parameter": pdb.set,
"update_rt_results": lambda mod: process_mod(rtr, mod), "update_rt_results": lambda mod: process_mod(rtr, mod),
"log": log.log
} }
scheduler = Scheduler(get_last_rid() + 1, worker_handlers) scheduler = Scheduler(get_last_rid() + 1, worker_handlers)
worker_handlers["scheduler_submit"] = scheduler.submit worker_handlers["scheduler_submit"] = scheduler.submit
@ -74,7 +87,8 @@ def main():
"devices": ddb.data, "devices": ddb.data,
"parameters": pdb.data, "parameters": pdb.data,
"rt_results": rtr, "rt_results": rtr,
"explist": repository.explist "explist": repository.explist,
"log": log.data
}) })
loop.run_until_complete(server_notify.start( loop.run_until_complete(server_notify.start(
args.bind, args.port_notify)) args.bind, args.port_notify))

View File

@ -1,7 +1,40 @@
import asyncio
from quamash import QtGui from quamash import QtGui
from pyqtgraph import dockarea from pyqtgraph import dockarea
from artiq.protocols.sync_struct import Subscriber
from artiq.gui.tools import ListSyncModel
class _LogModel(ListSyncModel):
def __init__(self, parent, init):
ListSyncModel.__init__(self,
["RID", "Message"],
parent, init)
def convert(self, v, column):
return v[column]
class LogDock(dockarea.Dock): class LogDock(dockarea.Dock):
def __init__(self): def __init__(self):
dockarea.Dock.__init__(self, "Log", size=(1000, 300)) dockarea.Dock.__init__(self, "Log", size=(1000, 300))
self.log = QtGui.QTableView()
self.log.setSelectionMode(QtGui.QAbstractItemView.NoSelection)
self.addWidget(self.log)
@asyncio.coroutine
def sub_connect(self, host, port):
self.subscriber = Subscriber("log", self.init_log_model)
yield from self.subscriber.connect(host, port)
@asyncio.coroutine
def sub_close(self):
yield from self.subscriber.close()
def init_log_model(self, init):
table_model = _LogModel(self.log, init)
self.log.setModel(table_model)
return table_model

View File

@ -4,6 +4,7 @@ import logging
import subprocess import subprocess
import traceback import traceback
import time import time
from functools import partial
from artiq.protocols import pyon from artiq.protocols import pyon
from artiq.tools import (asyncio_process_wait_timeout, asyncio_process_wait, from artiq.tools import (asyncio_process_wait_timeout, asyncio_process_wait,
@ -174,6 +175,8 @@ class Worker:
func = self.register_experiment func = self.register_experiment
else: else:
func = self.handlers[action] func = self.handlers[action]
if getattr(func, "worker_pass_rid", False):
func = partial(func, self.rid)
try: try:
data = func(**obj) data = func(**obj)
reply = {"status": "ok", "data": data} reply = {"status": "ok", "data": data}

View File

@ -44,6 +44,25 @@ def make_parent_action(action, argnames, exception=ParentActionError):
return parent_action return parent_action
class LogForwarder:
def __init__(self):
self.buffer = ""
to_parent = staticmethod(make_parent_action("log", "message"))
def write(self, data):
self.buffer += data
while "\n" in self.buffer:
i = self.buffer.index("\n")
self.to_parent(self.buffer[:i])
self.buffer = self.buffer[i+1:]
def flush(self):
pass
class ParentDDB: class ParentDDB:
get = make_parent_action("get_device", "name", KeyError) get = make_parent_action("get_device", "name", KeyError)
@ -133,7 +152,7 @@ def examine(dmgr, pdb, rdb, file):
def main(): def main():
sys.stdout = sys.stderr sys.stdout = sys.stderr = LogForwarder()
start_time = None start_time = None
rid = None rid = None