worker: cleaner termination on exception in user code, improve unittest

This commit is contained in:
Sebastien Bourdeauducq 2015-10-13 01:11:57 +08:00
parent fbf94f9b6d
commit 1d14975bd5
3 changed files with 35 additions and 2 deletions

View File

@ -21,6 +21,10 @@ class WorkerWatchdogTimeout(Exception):
pass pass
class WorkerException(Exception):
pass
class WorkerError(Exception): class WorkerError(Exception):
pass pass
@ -159,6 +163,8 @@ class Worker:
return True return True
elif action == "pause": elif action == "pause":
return False return False
elif action == "exception":
raise WorkerException
del obj["action"] del obj["action"]
if action == "create_watchdog": if action == "create_watchdog":
func = self.create_watchdog func = self.create_watchdog

View File

@ -1,6 +1,7 @@
import sys import sys
import time import time
import os import os
import traceback
from artiq.protocols import pyon from artiq.protocols import pyon
from artiq.tools import file_import from artiq.tools import file_import
@ -214,6 +215,9 @@ def main():
put_object({"action": "completed"}) put_object({"action": "completed"})
elif action == "terminate": elif action == "terminate":
break break
except:
traceback.print_exc()
put_object({"action": "exception"})
finally: finally:
device_mgr.close_devices() device_mgr.close_devices()

View File

@ -8,6 +8,22 @@ from artiq import *
from artiq.master.worker import * from artiq.master.worker import *
class SimpleExperiment(EnvExperiment):
def build(self):
pass
def run(self):
pass
class ExceptionTermination(EnvExperiment):
def build(self):
pass
def run(self):
raise TypeError
class WatchdogNoTimeout(EnvExperiment): class WatchdogNoTimeout(EnvExperiment):
def build(self): def build(self):
pass pass
@ -53,11 +69,11 @@ def _run_experiment(class_name):
"arguments": dict() "arguments": dict()
} }
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
worker = Worker() worker = Worker(handlers={"log": lambda message: None})
loop.run_until_complete(_call_worker(worker, expid)) loop.run_until_complete(_call_worker(worker, expid))
class WatchdogCase(unittest.TestCase): class WorkerCase(unittest.TestCase):
def setUp(self): def setUp(self):
if os.name == "nt": if os.name == "nt":
self.loop = asyncio.ProactorEventLoop() self.loop = asyncio.ProactorEventLoop()
@ -65,6 +81,13 @@ class WatchdogCase(unittest.TestCase):
self.loop = asyncio.new_event_loop() self.loop = asyncio.new_event_loop()
asyncio.set_event_loop(self.loop) asyncio.set_event_loop(self.loop)
def test_simple_run(self):
_run_experiment("SimpleExperiment")
def test_exception(self):
with self.assertRaises(WorkerException):
_run_experiment("ExceptionTermination")
def test_watchdog_no_timeout(self): def test_watchdog_no_timeout(self):
_run_experiment("WatchdogNoTimeout") _run_experiment("WatchdogNoTimeout")