Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: f695715d5666
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4c4da77cc805
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Jan 5, 2015

  1. Copy the full SHA
    f9d4056 View commit details
  2. Copy the full SHA
    4c4da77 View commit details
Showing with 51 additions and 28 deletions.
  1. +23 −7 artiq/gui/scheduler.py
  2. +18 −15 artiq/management/scheduler.py
  3. +10 −6 frontend/artiq_gui.py
30 changes: 23 additions & 7 deletions artiq/gui/scheduler.py
Original file line number Diff line number Diff line change
@@ -32,7 +32,9 @@ def convert(self, prid, x):


class SchedulerWindow(Window):
def __init__(self):
def __init__(self, schedule_ctl):
self.schedule_ctl = schedule_ctl

Window.__init__(self, title="Scheduler")
self.set_default_size(720, 570)

@@ -50,13 +52,13 @@ def __init__(self):
topvbox.pack_start(notebook, True, True, 0)

self.queue_store = Gtk.ListStore(int, str, str, str)
tree = Gtk.TreeView(self.queue_store)
self.queue_tree = Gtk.TreeView(self.queue_store)
for i, title in enumerate(["RID", "File", "Unit", "Timeout"]):
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(title, renderer, text=i)
tree.append_column(column)
self.queue_tree.append_column(column)
scroll = Gtk.ScrolledWindow()
scroll.add(tree)
scroll.add(self.queue_tree)
vbox = Gtk.VBox(spacing=6)
vbox.pack_start(scroll, True, True, 0)
hbox = Gtk.HBox(spacing=6)
@@ -67,31 +69,45 @@ def __init__(self):
button = Gtk.Button("Move down")
hbox.pack_start(button, True, True, 0)
button = Gtk.Button("Remove")
button.connect("clicked", self.remove_queue)
hbox.pack_start(button, True, True, 0)
vbox.pack_start(hbox, False, False, 0)
vbox.set_border_width(6)
notebook.insert_page(vbox, Gtk.Label("Queue"), -1)

self.periodic_store = Gtk.ListStore(str, int, str, str, str, str)
tree = Gtk.TreeView(self.periodic_store)
self.periodic_tree = Gtk.TreeView(self.periodic_store)
for i, title in enumerate(["Next run", "PRID", "File", "Unit",
"Timeout", "Period"]):
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(title, renderer, text=i)
tree.append_column(column)
self.periodic_tree.append_column(column)
scroll = Gtk.ScrolledWindow()
scroll.add(tree)
scroll.add(self.periodic_tree)
vbox = Gtk.VBox(spacing=6)
vbox.pack_start(scroll, True, True, 0)
hbox = Gtk.HBox(spacing=6)
button = Gtk.Button("Change period")
hbox.pack_start(button, True, True, 0)
button = Gtk.Button("Remove")
button.connect("clicked", self.remove_periodic)
hbox.pack_start(button, True, True, 0)
vbox.pack_start(hbox, False, False, 0)
vbox.set_border_width(6)
notebook.insert_page(vbox, Gtk.Label("Periodic schedule"), -1)

def remove_queue(self, widget):
store, selected = self.queue_tree.get_selection().get_selected()
if selected is not None:
rid = store[selected][0]
asyncio.Task(self.schedule_ctl.cancel_once(rid))

def remove_periodic(self, widget):
store, selected = self.periodic_tree.get_selection().get_selected()
if selected is not None:
prid = store[selected][1]
asyncio.Task(self.schedule_ctl.cancel_periodic(prid))

@asyncio.coroutine
def sub_connect(self, host, port):
self.queue_subscriber = Subscriber("queue", self.init_queue_store)
33 changes: 18 additions & 15 deletions artiq/management/scheduler.py
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ def __init__(self, worker_handlers):
self.worker = Worker(worker_handlers)
self.next_rid = 0
self.queue = Notifier([])
self.queue_count = asyncio.Semaphore(0)
self.queue_modified = asyncio.Event()
self.periodic = Notifier(dict())
self.periodic_modified = asyncio.Event()

@@ -39,12 +39,16 @@ def stop(self):
def run_once(self, run_params, timeout):
rid = self.new_rid()
self.queue.append((rid, run_params, timeout))
self.queue_count.release()
self.queue_modified.set()
return rid

def cancel_once(self, rid):
idx = next(idx for idx, (qrid, _, _) in enumerate(self.queue)
idx = next(idx for idx, (qrid, _, _)
in enumerate(self.queue.backing_struct)
if qrid == rid)
if idx == 0:
# Cannot cancel when already running
raise NotImplementedError
del self.queue[idx]

def run_periodic(self, run_params, timeout, period):
@@ -97,18 +101,17 @@ def _run_periodic(self):
def _schedule(self):
while True:
next_periodic = yield from self._run_periodic()
ev_queue = asyncio.Task(self.queue_count.acquire())
ev_periodic = asyncio.Task(self.periodic_modified.wait())
done, pend = yield from asyncio.wait(
[ev_queue, ev_periodic],
timeout=next_periodic,
return_when=asyncio.FIRST_COMPLETED)
self.periodic_modified.clear()
for t in pend:
t.cancel()

yield from self._run_periodic()
if ev_queue in done:
if self.queue.backing_struct:
rid, run_params, timeout = self.queue.backing_struct[0]
yield from self._run(rid, run_params, timeout)
del self.queue[0]
else:
self.queue_modified.clear()
self.periodic_modified.clear()
done, pend = yield from asyncio.wait(
[
self.queue_modified.wait(),
self.periodic_modified.wait()
],
timeout=next_periodic,
return_when=asyncio.FIRST_COMPLETED)
16 changes: 10 additions & 6 deletions frontend/artiq_gui.py
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
import gbulb
from gi.repository import Gtk

from artiq.management.pc_rpc import AsyncioClient
from artiq.gui.scheduler import SchedulerWindow
from artiq.gui.parameters import ParametersWindow

@@ -32,19 +33,22 @@ def main():
loop = asyncio.get_event_loop()
atexit.register(lambda: loop.close())

scheduler_win = SchedulerWindow()
# share the schedule control connection
schedule_ctl = AsyncioClient()
loop.run_until_complete(schedule_ctl.connect_rpc(
args.server, args.port_control, "master_schedule"))

scheduler_win = SchedulerWindow(schedule_ctl)
scheduler_win.connect("delete-event", Gtk.main_quit)
scheduler_win.show_all()

parameters_win = ParametersWindow()
parameters_win.connect("delete-event", Gtk.main_quit)
parameters_win.show_all()

loop.run_until_complete(scheduler_win.sub_connect(
args.server, args.port_notify))
atexit.register(
lambda: loop.run_until_complete(scheduler_win.sub_close()))

parameters_win = ParametersWindow()
parameters_win.connect("delete-event", Gtk.main_quit)
parameters_win.show_all()
loop.run_until_complete(parameters_win.sub_connect(
args.server, args.port_notify))
atexit.register(