The run_forever() API is prevalent throughout tickit. Components, adapters, schedulers etc. all have it. The idea is to collect this bucket of things into a giant asyncio task that is essentially :
asyncio.wait([thing.run_forever() for thing in all things])
This is convenient for running arbitrary simulations but painful to test. Tests need to know a component/adapter/scheduler has completed startup tasks and is ready to accept API calls. See https://github.com/dls-controls/tickit/issues/76. run_forever() often performs startup tasks opaquely, so the tests can't know when it's done. There have been various workarounds throughout the codebase such as exposing asyncio.Events or just having a sleep to allow servers time to start. None of these are ideal.
We also cannot easily shut things down between tests, there have been instances of tests breaking other tests. In some cases we have restored forcing task cancels.
I propose we go through and change all of these APIs from
The contract then is that start() performs all startup tasks and can be awaited on and stop() can be awaited on until all tasks have shut down. It is then easy to offer a fixture for a particular component et al.
Speculative Issue for Discussion
The
run_forever()
API is prevalent throughout tickit. Components, adapters, schedulers etc. all have it. The idea is to collect this bucket of things into a giant asyncio task that is essentially :This is convenient for running arbitrary simulations but painful to test. Tests need to know a component/adapter/scheduler has completed startup tasks and is ready to accept API calls. See https://github.com/dls-controls/tickit/issues/76.
run_forever()
often performs startup tasks opaquely, so the tests can't know when it's done. There have been various workarounds throughout the codebase such as exposingasyncio.Event
s or just having a sleep to allow servers time to start. None of these are ideal.We also cannot easily shut things down between tests, there have been instances of tests breaking other tests. In some cases we have restored forcing task cancels.
I propose we go through and change all of these APIs from
to
The contract then is that
start()
performs all startup tasks and can be awaited on andstop()
can be awaited on until all tasks have shut down. It is then easy to offer a fixture for a particular component et al.Tagging for discussion: @abbiemery @coretl @tpoliaw @DiamondJoseph