-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reinstate DeviceInitializationController
#881
base: main
Are you sure you want to change the base?
Reinstate DeviceInitializationController
#881
Conversation
b492c0c
to
e47b9f7
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #881 +/- ##
==========================================
+ Coverage 95.63% 95.68% +0.04%
==========================================
Files 128 128
Lines 5273 5331 +58
==========================================
+ Hits 5043 5101 +58
Misses 230 230 ☔ View full report in Codecov by Sentry. |
mock: bool, | ||
skip: SkipType, | ||
): | ||
self._factory: Callable[[], D] = functools.lru_cache(factory) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should behave in a similar way to the previous cache implementation, but we now have a lot of layers of caching:
3 caches is not ideal, especially for 2 use cases. It may be that we have to leave it like this and remove it once device_instantiation
is gone because each use case routes to difference caches in different ways:
blueapi | python shell (manual call) | python shell (calling make_all_devices ) |
|
---|---|---|---|
via device_instantiation |
BlueskyContext.devices |
ACTIVE_DEVICES |
ACTIVE_DEVICES |
via device_factory |
BlueskyContext.devices |
DeviceInitializationController.lru_cache |
ACTIVE_DEVICES |
We should think about where to cache things long-term. A single place would be ideal, thoughts welcome.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't see where make_all_devices
uses ACTIVE_DEVICES
other than it being called by device_instantiation
? So is it not:
blueapi | python shell (manual call) | python shell (calling make_all_devices ) |
|
---|---|---|---|
via device_instantiation |
BlueskyContext.devices |
ACTIVE_DEVICES |
ACTIVE_DEVICES |
via device_factory |
BlueskyContext.devices |
DeviceInitializationController.lru_cache |
DeviceInitializationController.lru_cache |
In which case the two caches are just the old one and the new one and I think we can then just remove the need for the new device factory to put anything into ACTIVE_DEVICES
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is where it uses ACTIVE_DEVICES
, albeit in a write-only capacity:
controller.add_callback(lambda device: cache_device(device, factory.__name__)) |
So maybe you're right, can we get away without that and have a clean separation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think there's no need for the new instantiation method to write to it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, although I had to change this test so it no longer relies on ACTIVE_DEVICES
, see what you think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, some comments in code. Additionally, I don;t think the system tests are working. When I run dodal connect i22
it passes but if I change a device to be the wrong PV it still passes, I would expect it to fail
src/dodal/beamlines/i22.py
Outdated
crystal_1_metadata = CrystalMetadata( | ||
usage="Bragg", | ||
type="silicon", | ||
reflection=(1, 1, 1), | ||
d_spacing=(3.13475, "nm"), | ||
) | ||
crystal_2_metadata = CrystalMetadata( | ||
usage="Bragg", | ||
type="silicon", | ||
reflection=(1, 1, 1), | ||
d_spacing=(3.13475, "nm"), | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should: I think the make_crystal_metadata_from_material
is cleaner
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch
mock: bool, | ||
skip: SkipType, | ||
): | ||
self._factory: Callable[[], D] = functools.lru_cache(factory) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't see where make_all_devices
uses ACTIVE_DEVICES
other than it being called by device_instantiation
? So is it not:
blueapi | python shell (manual call) | python shell (calling make_all_devices ) |
|
---|---|---|---|
via device_instantiation |
BlueskyContext.devices |
ACTIVE_DEVICES |
ACTIVE_DEVICES |
via device_factory |
BlueskyContext.devices |
DeviceInitializationController.lru_cache |
DeviceInitializationController.lru_cache |
In which case the two caches are just the old one and the new one and I think we can then just remove the need for the new device factory to put anything into ACTIVE_DEVICES
?
assert mirror.connect.call_count == 1 # type: ignore | ||
|
||
|
||
def test_multiple_layers_of_lru_caching_does_not_affect_device(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: It's not clear why this testing the multiple layers of cache is needed, would suggest a docstring as to why it's important to test
assert mirror.connect.call_count == 1 # type: ignore | ||
|
||
|
||
def test_multiple_layers_of_lru_caching_does_not_affect_device(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should: I think it would be good to test that the returned devices are the same without having the extra cache here too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's implicitly covered by test_device_factory_can_rename
but I think you may be right that it deserves its own test
@DominicOram I'm aware the system tests are unhappy, should have commented here, sorry about that. |
No worries, the |
It will be addressed here, I don't want to merge this without addressing this problem, I just thought it had already been fixed in #858, but apparently not... |
* Add DeviceFactory decorator * Convert i22 beamline to use DeviceFactory * Documenting potential pitfall with repeated connect/mock
…he implementation
ed41f3b
to
412a4c7
Compare
_, _, exceptions = module_and_devices_for_beamline | ||
if len(exceptions) > 0: | ||
raise NotConnected(exceptions) | ||
# Pass test if there were no exceptions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could: This change is fine by me. You could also still check follows_bluesky_protocols
for all returned devices but I'm not sure it gives you loads. If we're not using follows_bluesky_protocols
now though we should remove it.
@DominicOram I've changed my mind about this having realised that this bug also affects I'm going to take over and finish #865 to address. |
Fixes #878
Instructions to reviewer on how to test:
Checks for reviewer
dodal connect ${BEAMLINE}