forked from M-Labs/artiq
worker: cleaner termination on exception in user code, improve unittest
This commit is contained in:
parent
fbf94f9b6d
commit
1d14975bd5
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue