parent
5d91a0112a
commit
ff6f8151c9
|
@ -100,13 +100,17 @@ def main(argv):
|
|||
print(' '.join(subargv))
|
||||
os.execv(subargv[0], subargv)
|
||||
|
||||
logging.basicConfig()
|
||||
logging.getLogger().setLevel({
|
||||
'debug': logging.DEBUG,
|
||||
'info': logging.INFO,
|
||||
'warning': logging.WARNING,
|
||||
'error': logging.ERROR,
|
||||
'critical': logging.CRITICAL,
|
||||
root_logger = logging.getLogger()
|
||||
for handler in root_logger.handlers:
|
||||
root_logger.removeHandler(handler)
|
||||
logging.basicConfig(
|
||||
format='%(levelname)-8s:%(process)5s:%(thread)08x:%(name)s: %(message)s',
|
||||
level={
|
||||
'debug': logging.DEBUG,
|
||||
'info': logging.INFO,
|
||||
'warning': logging.WARNING,
|
||||
'error': logging.ERROR,
|
||||
'critical': logging.CRITICAL,
|
||||
}[args.log_level])
|
||||
|
||||
if args.rebuild:
|
||||
|
|
|
@ -68,30 +68,13 @@ class AudioProcClient(
|
|||
self.window.handle_pipeline_status(status)
|
||||
|
||||
|
||||
class AudioProcProcessImpl(object):
|
||||
def __init__(self, event_loop):
|
||||
super().__init__()
|
||||
self.event_loop = event_loop
|
||||
self.server = ipc.Server(self.event_loop, 'process')
|
||||
|
||||
async def setup(self):
|
||||
await self.server.setup()
|
||||
|
||||
async def cleanup(self):
|
||||
await self.server.cleanup()
|
||||
|
||||
|
||||
class AudioProcProcess(
|
||||
audioproc_process.AudioProcProcessMixin, AudioProcProcessImpl):
|
||||
pass
|
||||
|
||||
|
||||
class AudioPlaygroundApp(QtWidgets.QApplication):
|
||||
def __init__(self):
|
||||
super().__init__(['noisipg'])
|
||||
|
||||
async def main(self, event_loop):
|
||||
audioproc = AudioProcProcess(event_loop)
|
||||
audioproc = audioproc_process.AudioProcProcess(
|
||||
name='audioproc', event_loop=event_loop, manager=None)
|
||||
await audioproc.setup()
|
||||
try:
|
||||
window = AudioPlaygroundWindow(event_loop)
|
||||
|
|
|
@ -52,24 +52,6 @@ class TestClient(audioproc_client.AudioProcClientMixin, TestClientImpl):
|
|||
pass
|
||||
|
||||
|
||||
class TestAudioProcProcessImpl(object):
|
||||
def __init__(self, event_loop):
|
||||
super().__init__()
|
||||
self.event_loop = event_loop
|
||||
self.server = ipc.Server(self.event_loop, 'audioproc')
|
||||
|
||||
async def setup(self):
|
||||
await self.server.setup()
|
||||
|
||||
async def cleanup(self):
|
||||
await self.server.cleanup()
|
||||
|
||||
|
||||
class TestAudioProcProcess(
|
||||
audioproc_process.AudioProcProcessMixin, TestAudioProcProcessImpl):
|
||||
pass
|
||||
|
||||
|
||||
class ProxyTest(asynctest.TestCase):
|
||||
async def setUp(self):
|
||||
self.passthru_description = node_db.ProcessorDescription(
|
||||
|
@ -89,7 +71,8 @@ class ProxyTest(asynctest.TestCase):
|
|||
direction=node_db.PortDirection.Output),
|
||||
])
|
||||
|
||||
self.audioproc_process = TestAudioProcProcess(self.loop)
|
||||
self.audioproc_process = audioproc_process.AudioProcProcess(
|
||||
name='audioproc', event_loop=self.loop, manager=None)
|
||||
await self.audioproc_process.setup()
|
||||
self.audioproc_task = self.loop.create_task(
|
||||
self.audioproc_process.run())
|
||||
|
|
|
@ -99,9 +99,9 @@ class Session(object):
|
|||
self.publish_mutation(self.pending_mutations.pop(0))
|
||||
|
||||
|
||||
class AudioProcProcessMixin(object):
|
||||
def __init__(self, *args, shm=None, profile_path=None, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
class AudioProcProcess(core.ProcessBase):
|
||||
def __init__(self, *, shm=None, profile_path=None, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.shm_name = shm
|
||||
self.profile_path = profile_path
|
||||
self.shm = None
|
||||
|
@ -382,5 +382,5 @@ class AudioProcProcessMixin(object):
|
|||
self.__vm.dump()
|
||||
|
||||
|
||||
class AudioProcProcess(AudioProcProcessMixin, core.ProcessImpl):
|
||||
class AudioProcSubprocess(core.SubprocessMixin, AudioProcProcess):
|
||||
pass
|
||||
|
|
|
@ -33,7 +33,9 @@ from .model_base import (
|
|||
DeferredReference,
|
||||
)
|
||||
from .process_manager import (
|
||||
ProcessManager, ProcessImpl
|
||||
ProcessManager,
|
||||
ProcessBase,
|
||||
SubprocessMixin,
|
||||
)
|
||||
from .callbacks import (
|
||||
CallbackRegistry,
|
||||
|
|
|
@ -244,9 +244,11 @@ class ChildCollector(object):
|
|||
self.__stop = threading.Event()
|
||||
self.__thread = threading.Thread(target=self.__main)
|
||||
self.__thread.start()
|
||||
logger.info("Started ChildCollector thread 0x%08x", self.__thread.ident)
|
||||
|
||||
def cleanup(self):
|
||||
if self.__thread is not None:
|
||||
logger.info("Stopping ChildCollector thread 0x%08x", self.__thread.ident)
|
||||
self.__stop.set()
|
||||
self.__thread.join()
|
||||
self.__thread = None
|
||||
|
@ -331,15 +333,19 @@ class ChildCollector(object):
|
|||
|
||||
|
||||
class ProcessManager(object):
|
||||
def __init__(self, event_loop):
|
||||
def __init__(self, event_loop, collect_stats=True):
|
||||
self._event_loop = event_loop
|
||||
self._processes = {}
|
||||
self._sigchld_received = asyncio.Event()
|
||||
|
||||
self._server = ipc.Server(event_loop, 'manager')
|
||||
self._stats_collector = stats.Collector()
|
||||
self._child_collector = ChildCollector(
|
||||
self._stats_collector)
|
||||
|
||||
if collect_stats:
|
||||
self._stats_collector = stats.Collector()
|
||||
self._child_collector = ChildCollector(self._stats_collector)
|
||||
else:
|
||||
self._stats_collector = None
|
||||
self._child_collector = None
|
||||
|
||||
@property
|
||||
def server(self):
|
||||
|
@ -356,10 +362,13 @@ class ProcessManager(object):
|
|||
'STATS_FETCH', self.handle_stats_fetch)
|
||||
|
||||
await self._server.setup()
|
||||
self._child_collector.setup()
|
||||
|
||||
if self._child_collector is not None:
|
||||
self._child_collector.setup()
|
||||
|
||||
async def cleanup(self):
|
||||
self._child_collector.cleanup()
|
||||
if self._child_collector is not None:
|
||||
self._child_collector.cleanup()
|
||||
|
||||
await self.terminate_all_children()
|
||||
await self._server.cleanup()
|
||||
|
@ -420,8 +429,8 @@ class ProcessManager(object):
|
|||
for sig in signal.Signals:
|
||||
self._event_loop.remove_signal_handler(sig)
|
||||
|
||||
# Clear all stats inherited from the manager process.
|
||||
stats.registry.clear()
|
||||
# Create a new stats registry for this process.
|
||||
stats.registry = stats.Registry()
|
||||
|
||||
# Close the "other ends" of the pipes.
|
||||
os.close(request_out)
|
||||
|
@ -494,7 +503,7 @@ class ProcessManager(object):
|
|||
proc.pid = pid
|
||||
proc.create_loggers()
|
||||
|
||||
proc.logger.info("Created new subprocess.")
|
||||
proc.logger.info("Created new subprocess '%s' (%s).", name, cls)
|
||||
|
||||
await proc.setup_std_handlers(
|
||||
self._event_loop, stdout_in, stderr_in, logger_in)
|
||||
|
@ -505,7 +514,10 @@ class ProcessManager(object):
|
|||
|
||||
stub_address = await child_connection.read_async(self._event_loop)
|
||||
|
||||
self._child_collector.add_child(pid, child_connection)
|
||||
if self._child_collector is not None:
|
||||
self._child_collector.add_child(pid, child_connection)
|
||||
else:
|
||||
child_connection.close()
|
||||
|
||||
proc.address = stub_address.decode('utf-8')
|
||||
logger.info(
|
||||
|
@ -575,13 +587,18 @@ class ProcessManager(object):
|
|||
dead_children.add(pid)
|
||||
|
||||
for pid in dead_children:
|
||||
self._child_collector.remove_child(pid)
|
||||
if self._child_collector is not None:
|
||||
self._child_collector.remove_child(pid)
|
||||
del self._processes[pid]
|
||||
|
||||
def handle_stats_list(self):
|
||||
if self._stats_collector is None:
|
||||
return RuntimeError("Stats collection not enabled.")
|
||||
return self._stats_collector.list_stats()
|
||||
|
||||
def handle_stats_fetch(self, expressions):
|
||||
if self._stats_collector is None:
|
||||
return RuntimeError("Stats collection not enabled.")
|
||||
return self._stats_collector.fetch_stats(expressions)
|
||||
|
||||
|
||||
|
@ -596,10 +613,11 @@ class ChildConnectionHandler(object):
|
|||
self.__stop = eventfd.EventFD()
|
||||
self.__thread = threading.Thread(target=self.__main)
|
||||
self.__thread.start()
|
||||
logger.info("Started ChildConnectionHandler thread 0x%08x", self.__thread.ident)
|
||||
|
||||
def cleanup(self):
|
||||
if self.__thread is not None:
|
||||
logger.info("Stopping ChildConnectionHandler...")
|
||||
logger.info("Stopping ChildConnectionHandler thread 0x%08x...", self.__thread.ident)
|
||||
self.__stop.set()
|
||||
self.__thread.join()
|
||||
self.__thread = None
|
||||
|
@ -633,16 +651,32 @@ class ChildConnectionHandler(object):
|
|||
logger.info("ChildConnectionHandler stopped.")
|
||||
|
||||
|
||||
class ProcessImpl(object):
|
||||
def __init__(self, name, manager_address):
|
||||
class ProcessBase(object):
|
||||
def __init__(self, *, name, manager, event_loop):
|
||||
self.name = name
|
||||
self.manager_address = manager_address
|
||||
self.event_loop = None
|
||||
self.pid = os.getpid()
|
||||
|
||||
self.manager = None
|
||||
self.manager = manager
|
||||
self.event_loop = event_loop
|
||||
self.server = None
|
||||
|
||||
async def setup(self):
|
||||
self.server = ipc.Server(self.event_loop, self.name)
|
||||
await self.server.setup()
|
||||
|
||||
async def cleanup(self):
|
||||
await self.server.cleanup()
|
||||
self.server = None
|
||||
|
||||
async def run(self):
|
||||
raise NotImplementedError(type(self).__name__)
|
||||
|
||||
|
||||
class SubprocessMixin(object):
|
||||
def __init__(self, *, manager_address, **kwargs):
|
||||
super().__init__(manager=None, event_loop=None, **kwargs)
|
||||
|
||||
self.manager_address = manager_address
|
||||
self.pid = os.getpid()
|
||||
|
||||
def create_event_loop(self):
|
||||
return asyncio.new_event_loop()
|
||||
|
||||
|
@ -664,53 +698,42 @@ class ProcessImpl(object):
|
|||
self.main_async(child_connection, *args, **kwargs))
|
||||
finally:
|
||||
logger.info("Closing event loop...")
|
||||
self.event_loop.stop()
|
||||
self.event_loop.run_until_complete(
|
||||
asyncio.gather(*asyncio.Task.all_tasks(self.event_loop)))
|
||||
self.event_loop.stop()
|
||||
self.event_loop.close()
|
||||
logger.info("Event loop closed.")
|
||||
|
||||
async def main_async(self, child_connection, *args, **kwargs):
|
||||
self.manager = ManagerStub(self.event_loop, self.manager_address)
|
||||
async with self.manager:
|
||||
self.server = ipc.Server(self.event_loop, self.name)
|
||||
async with self.server:
|
||||
try:
|
||||
logger.info("Setting up process.")
|
||||
await self.setup()
|
||||
|
||||
stub_address = self.server.address.encode('utf-8')
|
||||
child_connection.write(stub_address)
|
||||
|
||||
child_connection_handler = ChildConnectionHandler(child_connection)
|
||||
child_connection_handler.setup()
|
||||
try:
|
||||
logger.info("Setting up process.")
|
||||
await self.setup()
|
||||
logger.info("Entering run method.")
|
||||
return await self.run(*args, **kwargs)
|
||||
|
||||
stub_address = self.server.address.encode('utf-8')
|
||||
child_connection.write(stub_address)
|
||||
|
||||
child_connection_handler = ChildConnectionHandler(child_connection)
|
||||
child_connection_handler.setup()
|
||||
try:
|
||||
logger.info("Entering run method.")
|
||||
return await self.run(*args, **kwargs)
|
||||
|
||||
except Exception as exc:
|
||||
logger.error(
|
||||
"Unhandled exception in process %s:\n%s",
|
||||
self.name, traceback.format_exc())
|
||||
raise
|
||||
|
||||
finally:
|
||||
logger.info("Closing child connection...")
|
||||
child_connection_handler.cleanup()
|
||||
child_connection.close()
|
||||
logger.info("Child connection closed.")
|
||||
except Exception as exc:
|
||||
logger.error(
|
||||
"Unhandled exception in process %s:\n%s",
|
||||
self.name, traceback.format_exc())
|
||||
raise
|
||||
|
||||
finally:
|
||||
await self.cleanup()
|
||||
logger.info("Closing child connection...")
|
||||
child_connection_handler.cleanup()
|
||||
child_connection.close()
|
||||
logger.info("Child connection closed.")
|
||||
|
||||
async def setup(self):
|
||||
pass
|
||||
|
||||
async def cleanup(self):
|
||||
pass
|
||||
|
||||
async def run(self):
|
||||
raise NotImplementedError("Subclass must override run")
|
||||
finally:
|
||||
await self.cleanup()
|
||||
|
||||
|
||||
class SetPIDHandler(logging.Handler):
|
||||
|
|
|
@ -33,74 +33,69 @@ from . import process_manager
|
|||
|
||||
|
||||
class ProcessManagerTest(asynctest.TestCase):
|
||||
@unittest.skip("FIXME: test hangs infinitely.")
|
||||
async def test_simple(self):
|
||||
class Child(process_manager.ProcessImpl):
|
||||
def __init__(self, foo, **kwargs):
|
||||
class Child(process_manager.SubprocessMixin, process_manager.ProcessBase):
|
||||
def __init__(self, *, foo, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
assert foo == 'bar'
|
||||
|
||||
async def run(self):
|
||||
pass
|
||||
|
||||
async with process_manager.ProcessManager(self.loop) as mgr:
|
||||
async with process_manager.ProcessManager(self.loop, collect_stats=False) as mgr:
|
||||
proc = await mgr.start_process('test', Child, foo='bar')
|
||||
await proc.wait()
|
||||
self.assertEqual(proc.returncode, 0)
|
||||
|
||||
@unittest.skip("FIXME: test hangs infinitely.")
|
||||
async def test_child_fails(self):
|
||||
class Child(process_manager.ProcessImpl):
|
||||
class Child(process_manager.SubprocessMixin, process_manager.ProcessBase):
|
||||
async def run(self):
|
||||
sys.exit(2)
|
||||
os._exit(2)
|
||||
|
||||
async with process_manager.ProcessManager(self.loop) as mgr:
|
||||
async with process_manager.ProcessManager(self.loop, collect_stats=False) as mgr:
|
||||
proc = await mgr.start_process('test', Child)
|
||||
await proc.wait()
|
||||
self.assertEqual(proc.returncode, 2)
|
||||
|
||||
@unittest.skip("FIXME: test hangs infinitely.")
|
||||
async def test_child_killed(self):
|
||||
class Child(process_manager.ProcessImpl):
|
||||
class Child(process_manager.SubprocessMixin, process_manager.ProcessBase):
|
||||
async def run(self):
|
||||
os.kill(self.pid, signal.SIGKILL)
|
||||
|
||||
async with process_manager.ProcessManager(self.loop) as mgr:
|
||||
async with process_manager.ProcessManager(self.loop, collect_stats=False) as mgr:
|
||||
proc = await mgr.start_process('test', Child)
|
||||
await proc.wait()
|
||||
self.assertEqual(proc.returncode, 1)
|
||||
self.assertEqual(proc.signal, signal.SIGKILL)
|
||||
|
||||
@unittest.skip("FIXME: test hangs infinitely.")
|
||||
async def test_left_over(self):
|
||||
class Child(process_manager.ProcessImpl):
|
||||
class Child(process_manager.SubprocessMixin, process_manager.ProcessBase):
|
||||
async def run(self):
|
||||
while True:
|
||||
await asyncio.sleep(1)
|
||||
|
||||
async with process_manager.ProcessManager(self.loop) as mgr:
|
||||
async with process_manager.ProcessManager(self.loop, collect_stats=False) as mgr:
|
||||
stub = await mgr.start_process('test', Child)
|
||||
|
||||
@unittest.skip("FIXME: test hangs infinitely.")
|
||||
async def test_left_over_sigterm_fails(self):
|
||||
class Child(process_manager.ProcessImpl):
|
||||
class Child(process_manager.SubprocessMixin, process_manager.ProcessBase):
|
||||
async def run(self):
|
||||
signal.signal(signal.SIGTERM, signal.SIG_IGN)
|
||||
while True:
|
||||
await asyncio.sleep(1)
|
||||
|
||||
async with process_manager.ProcessManager(self.loop) as mgr:
|
||||
async with process_manager.ProcessManager(self.loop, collect_stats=False) as mgr:
|
||||
stub = await mgr.start_process('test', Child)
|
||||
await mgr.terminate_all_children(timeout=0.2)
|
||||
|
||||
async def test_capture_stdout(self):
|
||||
class Child(process_manager.ProcessImpl):
|
||||
class Child(process_manager.SubprocessMixin, process_manager.ProcessBase):
|
||||
async def run(self):
|
||||
for i in range(10):
|
||||
print(i)
|
||||
sys.stderr.write('goo')
|
||||
|
||||
async with process_manager.ProcessManager(self.loop) as mgr:
|
||||
async with process_manager.ProcessManager(self.loop, collect_stats=False) as mgr:
|
||||
proc = await mgr.start_process('test', Child)
|
||||
await proc.wait()
|
||||
self.assertEqual(proc.returncode, 0)
|
||||
|
|
|
@ -99,7 +99,7 @@ class Editor(object):
|
|||
while True:
|
||||
next_retry = time.time() + 5
|
||||
proc = await self.manager.start_process(
|
||||
'ui', 'noisicaa.ui.ui_process.UIProcess',
|
||||
'ui', 'noisicaa.ui.ui_process.UISubprocess',
|
||||
runtime_settings=self.runtime_settings,
|
||||
paths=self.paths)
|
||||
await proc.wait()
|
||||
|
@ -141,7 +141,7 @@ class Editor(object):
|
|||
# TODO: keep map of uri->proc, only create processes for new
|
||||
# URIs.
|
||||
proc = await self.manager.start_process(
|
||||
'project', 'noisicaa.music.project_process.ProjectProcess')
|
||||
'project', 'noisicaa.music.project_process.ProjectSubprocess')
|
||||
return proc.address
|
||||
|
||||
async def handle_create_audioproc_process(self, name, **kwargs):
|
||||
|
@ -149,7 +149,7 @@ class Editor(object):
|
|||
# names.
|
||||
proc = await self.manager.start_process(
|
||||
'audioproc<%s>' % name,
|
||||
'noisicaa.audioproc.audioproc_process.AudioProcProcess',
|
||||
'noisicaa.audioproc.audioproc_process.AudioProcSubprocess',
|
||||
**kwargs)
|
||||
return proc.address
|
||||
|
||||
|
@ -158,7 +158,7 @@ class Editor(object):
|
|||
if self.node_db_process is None:
|
||||
self.node_db_process = await self.manager.start_process(
|
||||
'node_db',
|
||||
'noisicaa.node_db.process.NodeDBProcess')
|
||||
'noisicaa.node_db.process.NodeDBSubprocess')
|
||||
|
||||
return self.node_db_process.address
|
||||
|
||||
|
@ -167,7 +167,7 @@ class Editor(object):
|
|||
if self.instrument_db_process is None:
|
||||
self.instrument_db_process = await self.manager.start_process(
|
||||
'instrument_db',
|
||||
'noisicaa.instrument_db.process.InstrumentDBProcess')
|
||||
'noisicaa.instrument_db.process.InstrumentDBSubprocess')
|
||||
|
||||
return self.instrument_db_process.address
|
||||
|
||||
|
|
|
@ -51,26 +51,10 @@ class TestClient(client.InstrumentDBClientMixin, TestClientImpl):
|
|||
pass
|
||||
|
||||
|
||||
class TestProcessImpl(object):
|
||||
def __init__(self, event_loop):
|
||||
super().__init__()
|
||||
self.event_loop = event_loop
|
||||
self.server = ipc.Server(self.event_loop, 'audioproc')
|
||||
|
||||
async def setup(self):
|
||||
await self.server.setup()
|
||||
|
||||
async def cleanup(self):
|
||||
await self.server.cleanup()
|
||||
|
||||
|
||||
class TestProcess(process.InstrumentDBProcessMixin, TestProcessImpl):
|
||||
pass
|
||||
|
||||
|
||||
class InstrumentDBClientTest(asynctest.TestCase):
|
||||
async def setUp(self):
|
||||
self.process = TestProcess(self.loop)
|
||||
self.process = process.InstrumentDBProcess(
|
||||
name='instrument_db', event_loop=self.loop, manager=None)
|
||||
await self.process.setup()
|
||||
self.process_task = self.loop.create_task(
|
||||
self.process.run())
|
||||
|
|
|
@ -80,9 +80,9 @@ class Session(object):
|
|||
self.pending_mutations.clear()
|
||||
|
||||
|
||||
class InstrumentDBProcessMixin(process_base.InstrumentDBProcessBase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
class InstrumentDBProcess(process_base.InstrumentDBProcessBase):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.sessions = {}
|
||||
self.db = None
|
||||
self.search_paths = [
|
||||
|
@ -168,5 +168,5 @@ class InstrumentDBProcessMixin(process_base.InstrumentDBProcessBase):
|
|||
return self.db.start_scan(self.search_paths, True)
|
||||
|
||||
|
||||
class InstrumentDBProcess(InstrumentDBProcessMixin, core.ProcessImpl):
|
||||
class InstrumentDBSubprocess(core.SubprocessMixin, InstrumentDBProcess):
|
||||
pass
|
||||
|
|
|
@ -20,7 +20,10 @@
|
|||
#
|
||||
# @end:license
|
||||
|
||||
class InstrumentDBProcessBase(object):
|
||||
from noisicaa import core
|
||||
|
||||
|
||||
class InstrumentDBProcessBase(core.ProcessBase):
|
||||
async def setup(self):
|
||||
await super().setup()
|
||||
|
||||
|
|
|
@ -57,24 +57,6 @@ from . import project_client
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestAudioProcProcessImpl(object):
|
||||
def __init__(self, event_loop, name):
|
||||
super().__init__()
|
||||
self.event_loop = event_loop
|
||||
self.server = ipc.Server(self.event_loop, name)
|
||||
|
||||
async def setup(self):
|
||||
await self.server.setup()
|
||||
|
||||
async def cleanup(self):
|
||||
await self.server.cleanup()
|
||||
|
||||
|
||||
class TestAudioProcProcess(
|
||||
audioproc_process.AudioProcProcessMixin, TestAudioProcProcessImpl):
|
||||
pass
|
||||
|
||||
|
||||
class TestAudioProcClientImpl(object):
|
||||
def __init__(self, event_loop, name):
|
||||
super().__init__()
|
||||
|
@ -137,7 +119,8 @@ class PlayerTest(asynctest.TestCase):
|
|||
self.callback_server = CallbackServer(self.loop)
|
||||
await self.callback_server.setup()
|
||||
|
||||
self.audioproc_server_main = TestAudioProcProcess(self.loop, 'main_process')
|
||||
self.audioproc_server_main = audioproc_process.AudioProcProcess(
|
||||
name='main_process', event_loop=self.loop, manager=None)
|
||||
await self.audioproc_server_main.setup()
|
||||
self.audioproc_server_main_task = self.loop.create_task(
|
||||
self.audioproc_server_main.run())
|
||||
|
@ -151,8 +134,8 @@ class PlayerTest(asynctest.TestCase):
|
|||
profile_path = None
|
||||
if constants.TEST_OPTS.ENABLE_PROFILER:
|
||||
profile_path = os.path.join(tempfile.gettempdir(), self.id() + '.prof')
|
||||
self.audioproc_server_player = TestAudioProcProcess(
|
||||
self.loop, 'player_process',
|
||||
self.audioproc_server_player = audioproc_process.AudioProcProcess(
|
||||
name='player_process', event_loop=self.loop, manager=None,
|
||||
profile_path=profile_path)
|
||||
await self.audioproc_server_player.setup()
|
||||
self.audioproc_server_player_task = self.loop.create_task(
|
||||
|
|
|
@ -55,25 +55,6 @@ class TestClient(project_client.ProjectClientMixin, TestClientImpl):
|
|||
pass
|
||||
|
||||
|
||||
class TestProjectProcessImpl(object):
|
||||
def __init__(self, event_loop, manager):
|
||||
super().__init__()
|
||||
self.event_loop = event_loop
|
||||
self.manager = manager
|
||||
self.server = ipc.Server(self.event_loop, 'project')
|
||||
|
||||
async def setup(self):
|
||||
await self.server.setup()
|
||||
|
||||
async def cleanup(self):
|
||||
await self.server.cleanup()
|
||||
|
||||
|
||||
class TestProjectProcess(
|
||||
project_process.ProjectProcessMixin, TestProjectProcessImpl):
|
||||
pass
|
||||
|
||||
|
||||
class AsyncSetupBase():
|
||||
async def setup(self):
|
||||
pass
|
||||
|
@ -81,20 +62,7 @@ class AsyncSetupBase():
|
|||
async def cleanup(self):
|
||||
pass
|
||||
|
||||
class TestNodeDBProcess(node_db.NodeDBProcessBase, AsyncSetupBase):
|
||||
def __init__(self, event_loop):
|
||||
super().__init__()
|
||||
self.event_loop = event_loop
|
||||
self.server = ipc.Server(self.event_loop, 'node_db')
|
||||
|
||||
async def setup(self):
|
||||
await super().setup()
|
||||
await self.server.setup()
|
||||
|
||||
async def cleanup(self):
|
||||
await self.server.cleanup()
|
||||
await super().cleanup()
|
||||
|
||||
class TestNodeDBProcess(node_db.NodeDBProcessBase):
|
||||
def handle_start_session(self, client_address, flags):
|
||||
return '123'
|
||||
|
||||
|
@ -104,7 +72,8 @@ class TestNodeDBProcess(node_db.NodeDBProcessBase, AsyncSetupBase):
|
|||
|
||||
class ProxyTest(asynctest.TestCase):
|
||||
async def setUp(self):
|
||||
self.node_db_process = TestNodeDBProcess(self.loop)
|
||||
self.node_db_process = TestNodeDBProcess(
|
||||
name='node_db', event_loop=self.loop, manager=None)
|
||||
await self.node_db_process.setup()
|
||||
|
||||
self.manager = mock.Mock()
|
||||
|
@ -113,8 +82,10 @@ class ProxyTest(asynctest.TestCase):
|
|||
return self.node_db_process.server.address
|
||||
self.manager.call.side_effect = mock_call
|
||||
|
||||
self.project_process = TestProjectProcess(self.loop, self.manager)
|
||||
self.project_process = project_process.ProjectProcess(
|
||||
name='project', manager=self.manager, event_loop=self.loop)
|
||||
await self.project_process.setup()
|
||||
|
||||
self.client = TestClient(self.loop)
|
||||
self.client.cls_map = model.cls_map
|
||||
await self.client.setup()
|
||||
|
|
|
@ -186,9 +186,9 @@ class NodeDBClient(node_db.NodeDBClientMixin, NodeDBClientImpl):
|
|||
pass
|
||||
|
||||
|
||||
class ProjectProcessMixin(object):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
class ProjectProcess(core.ProcessBase):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self._shutting_down = None
|
||||
|
||||
|
@ -488,5 +488,5 @@ class ProjectProcessMixin(object):
|
|||
session.set_values(data, from_client=True)
|
||||
|
||||
|
||||
class ProjectProcess(ProjectProcessMixin, core.ProcessImpl):
|
||||
class ProjectSubprocess(core.SubprocessMixin, ProjectProcess):
|
||||
pass
|
||||
|
|
|
@ -51,26 +51,10 @@ class TestClient(client.NodeDBClientMixin, TestClientImpl):
|
|||
pass
|
||||
|
||||
|
||||
class TestProcessImpl(object):
|
||||
def __init__(self, event_loop):
|
||||
super().__init__()
|
||||
self.event_loop = event_loop
|
||||
self.server = ipc.Server(self.event_loop, 'audioproc')
|
||||
|
||||
async def setup(self):
|
||||
await self.server.setup()
|
||||
|
||||
async def cleanup(self):
|
||||
await self.server.cleanup()
|
||||
|
||||
|
||||
class TestProcess(process.NodeDBProcessMixin, TestProcessImpl):
|
||||
pass
|
||||
|
||||
|
||||
class NodeDBClientTest(asynctest.TestCase):
|
||||
async def setUp(self):
|
||||
self.process = TestProcess(self.loop)
|
||||
self.process = process.NodeDBProcess(
|
||||
name='node_db', event_loop=self.loop, manager=None)
|
||||
await self.process.setup()
|
||||
self.process_task = self.loop.create_task(
|
||||
self.process.run())
|
||||
|
|
|
@ -54,9 +54,9 @@ class Session(object):
|
|||
await self.callback_stub.call('NODEDB_MUTATION', mutation)
|
||||
|
||||
|
||||
class NodeDBProcessMixin(process_base.NodeDBProcessBase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
class NodeDBProcess(process_base.NodeDBProcessBase):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.sessions = {}
|
||||
self.db = db.NodeDB()
|
||||
|
||||
|
@ -117,5 +117,5 @@ class NodeDBProcessMixin(process_base.NodeDBProcessBase):
|
|||
return self.db.start_scan()
|
||||
|
||||
|
||||
class NodeDBProcess(NodeDBProcessMixin, core.ProcessImpl):
|
||||
class NodeDBSubprocess(core.SubprocessMixin, NodeDBProcess):
|
||||
pass
|
||||
|
|
|
@ -20,7 +20,10 @@
|
|||
#
|
||||
# @end:license
|
||||
|
||||
class NodeDBProcessBase(object):
|
||||
from noisicaa import core
|
||||
|
||||
|
||||
class NodeDBProcessBase(core.ProcessBase):
|
||||
async def setup(self):
|
||||
await super().setup()
|
||||
|
||||
|
|
|
@ -34,8 +34,8 @@ from . import editor_app
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class UIProcessMixin(object):
|
||||
def __init__(self, runtime_settings, paths, **kwargs):
|
||||
class UISubprocess(core.SubprocessMixin, core.ProcessBase):
|
||||
def __init__(self, *, runtime_settings, paths, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.app = self.create_app(self, runtime_settings, paths)
|
||||
|
@ -69,7 +69,3 @@ class UIProcessMixin(object):
|
|||
def handle_signal(self, sig):
|
||||
logger.info("%s received.", sig.name)
|
||||
self.quit(0)
|
||||
|
||||
|
||||
class UIProcess(UIProcessMixin, core.ProcessImpl):
|
||||
pass
|
||||
|
|
|
@ -30,6 +30,7 @@ import asynctest
|
|||
from PyQt5.QtCore import Qt
|
||||
from PyQt5 import QtGui
|
||||
|
||||
from noisicaa import core
|
||||
from noisicaa import instrument_db
|
||||
from noisicaa import node_db
|
||||
from noisicaa.core import ipc
|
||||
|
@ -139,20 +140,7 @@ class AsyncSetupBase():
|
|||
pass
|
||||
|
||||
|
||||
class TestNodeDBProcess(node_db.NodeDBProcessBase, AsyncSetupBase):
|
||||
def __init__(self, event_loop):
|
||||
super().__init__()
|
||||
self.event_loop = event_loop
|
||||
self.server = ipc.Server(self.event_loop, 'node_db')
|
||||
|
||||
async def setup(self):
|
||||
await super().setup()
|
||||
await self.server.setup()
|
||||
|
||||
async def cleanup(self):
|
||||
await self.server.cleanup()
|
||||
await super().cleanup()
|
||||
|
||||
class TestNodeDBProcess(node_db.NodeDBProcessBase):
|
||||
def handle_start_session(self, client_address, flags):
|
||||
return '123'
|
||||
|
||||
|
@ -163,20 +151,7 @@ class TestNodeDBProcess(node_db.NodeDBProcessBase, AsyncSetupBase):
|
|||
pass
|
||||
|
||||
|
||||
class TestInstrumentDBProcess(instrument_db.InstrumentDBProcessBase, AsyncSetupBase):
|
||||
def __init__(self, event_loop):
|
||||
super().__init__()
|
||||
self.event_loop = event_loop
|
||||
self.server = ipc.Server(self.event_loop, 'instrument_db')
|
||||
|
||||
async def setup(self):
|
||||
await super().setup()
|
||||
await self.server.setup()
|
||||
|
||||
async def cleanup(self):
|
||||
await self.server.cleanup()
|
||||
await super().cleanup()
|
||||
|
||||
class TestInstrumentDBProcess(instrument_db.InstrumentDBProcessBase):
|
||||
def handle_start_session(self, client_address, flags):
|
||||
return '123'
|
||||
|
||||
|
@ -187,18 +162,10 @@ class TestInstrumentDBProcess(instrument_db.InstrumentDBProcessBase, AsyncSetupB
|
|||
pass
|
||||
|
||||
|
||||
class MockProcess(object):
|
||||
def __init__(self, event_loop, manager):
|
||||
self.event_loop = event_loop
|
||||
self.manager = manager
|
||||
class MockProcess(core.ProcessBase):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.project = None
|
||||
self.server = ipc.Server(self.event_loop, 'ui')
|
||||
|
||||
async def setup(self):
|
||||
await self.server.setup()
|
||||
|
||||
async def cleanup(self):
|
||||
await self.server.cleanup()
|
||||
|
||||
|
||||
class MockApp(BaseEditorApp):
|
||||
|
@ -221,10 +188,12 @@ class UITest(asynctest.TestCase):
|
|||
app = None
|
||||
|
||||
async def setUp(self):
|
||||
self.node_db_process = TestNodeDBProcess(self.loop)
|
||||
self.node_db_process = TestNodeDBProcess(
|
||||
name='node_db', event_loop=self.loop, manager=None)
|
||||
await self.node_db_process.setup()
|
||||
|
||||
self.instrument_db_process = TestInstrumentDBProcess(self.loop)
|
||||
self.instrument_db_process = TestInstrumentDBProcess(
|
||||
name='instrument_db', event_loop=self.loop, manager=None)
|
||||
await self.instrument_db_process.setup()
|
||||
|
||||
self.manager = mock.Mock()
|
||||
|
@ -238,7 +207,8 @@ class UITest(asynctest.TestCase):
|
|||
|
||||
self.manager.call.side_effect = mock_call
|
||||
|
||||
self.process = MockProcess(self.loop, self.manager)
|
||||
self.process = MockProcess(
|
||||
name='ui', event_loop=self.loop, manager=self.manager)
|
||||
await self.process.setup()
|
||||
|
||||
if UITest.app is None:
|
||||
|
|
Loading…
Reference in New Issue