-
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
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.98% 96.03% +0.04%
==========================================
Files 136 136
Lines 5561 5623 +62
==========================================
+ Hits 5338 5400 +62
Misses 223 223 ☔ View full report in Codecov by Sentry. 🚨 Try these New Features:
|
src/dodal/utils.py
Outdated
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
src/dodal/utils.py
Outdated
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... |
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. |
ce4b3c8
to
f7a901f
Compare
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 found a few issues from running dodal connect i22
and comparing to main
fake_with_ophyd_sim, | ||
) | ||
@device_factory() | ||
def linkam() -> Linkam3: |
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: The linkam was previously skipped, should it not still be?
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 question, it was skipped back when make_all_devices
raised an exception if any device couldn't connect. Now we've instead got it to return an exception and let the user handle it, it matters less. I will restore the skip though as removing it is out of scope and can be handled in another PR.
] | ||
assert ( | ||
len(devices_not_following_bluesky_protocols) == 0 | ||
), f"{devices_not_following_bluesky_protocols} do not follow blueesky protocols" |
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:
), f"{devices_not_following_bluesky_protocols} do not follow blueesky protocols" | |
), f"{devices_not_following_bluesky_protocols} do not follow bluesky protocols" |
src/dodal/beamlines/i22.py
Outdated
) | ||
@device_factory() | ||
def linkam() -> Linkam3: | ||
return Linkam3(prefix=f"{PREFIX.beamline_prefix}-EA-TEMPC-05") |
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: I suspect we need a :
after the prefix here. Hard to tell 100% as it doesn't connect either way and was previously being skipped so we would have missed it anyway
return Linkam3(prefix=f"{PREFIX.beamline_prefix}-EA-TEMPC-05") | |
return Linkam3(prefix=f"{PREFIX.beamline_prefix}-EA-TEMPC-05:") |
src/dodal/beamlines/i22.py
Outdated
@device_factory() | ||
def hfm() -> FocusingMirror: | ||
return FocusingMirror( | ||
prefix=f"{PREFIX.beamline_prefix}|-OP-KBM-01:HFM:", |
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.
Must: Accidental |
after the prefix here.
prefix=f"{PREFIX.beamline_prefix}|-OP-KBM-01:HFM:", | |
prefix=f"{PREFIX.beamline_prefix}-OP-KBM-01:HFM:", |
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.
Great, thank you!
88b5aa5
to
860b6bf
Compare
* Add DeviceFactory decorator * Convert i22 beamline to use DeviceFactory * Documenting potential pitfall with repeated connect/mock
…he implementation
…ers and add tests accordingly
860b6bf
to
35d6808
Compare
Fixes #878
Instructions to reviewer on how to test:
Checks for reviewer
dodal connect ${BEAMLINE}