Skip to content
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

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

callumforrester
Copy link
Contributor

Fixes #878

Instructions to reviewer on how to test:

  1. Run unit tests
  2. Run system tests for I22
  3. Run system tests for at least 1 other beamline

Checks for reviewer

  • Would the PR title make sense to a scientist on a set of release notes
  • If a new device has been added does it follow the standards
  • If changing the API for a pre-existing device, ensure that any beamlines using this device have updated their Bluesky plans accordingly
  • Have the connection tests for the relevant beamline(s) been run via dodal connect ${BEAMLINE}

@callumforrester callumforrester force-pushed the 878-reinstate-device-initialization-controller branch 3 times, most recently from b492c0c to e47b9f7 Compare November 6, 2024 14:37
Copy link

codecov bot commented Nov 6, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 95.68%. Comparing base (fc296b5) to head (b2c9475).

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.
📢 Have feedback on the report? Share it here.

mock: bool,
skip: SkipType,
):
self._factory: Callable[[], D] = functools.lru_cache(factory)
Copy link
Contributor Author

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:

device-caching(1)

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.

Copy link
Contributor

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?

Copy link
Contributor Author

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?

Copy link
Contributor

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

Copy link
Contributor Author

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

@callumforrester callumforrester marked this pull request as ready for review November 6, 2024 15:17
Copy link
Contributor

@DominicOram DominicOram left a 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

Comment on lines 125 to 137
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"),
)
Copy link
Contributor

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

Copy link
Contributor Author

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)
Copy link
Contributor

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():
Copy link
Contributor

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():
Copy link
Contributor

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

Copy link
Contributor Author

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

@callumforrester
Copy link
Contributor Author

@DominicOram I'm aware the system tests are unhappy, should have commented here, sorry about that.

@DominicOram
Copy link
Contributor

DominicOram commented Nov 11, 2024

@DominicOram I'm aware the system tests are unhappy, should have commented here, sorry about that

No worries, the Instructions to test imply they are ok though. Will this be addressed in another issue or part of this one?

@callumforrester
Copy link
Contributor Author

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...

@callumforrester callumforrester force-pushed the 878-reinstate-device-initialization-controller branch from ed41f3b to 412a4c7 Compare November 11, 2024 14:41
_, _, exceptions = module_and_devices_for_beamline
if len(exceptions) > 0:
raise NotConnected(exceptions)
# Pass test if there were no exceptions
Copy link
Contributor

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.

@callumforrester
Copy link
Contributor Author

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...

@DominicOram I've changed my mind about this having realised that this bug also affects device_instantiation in main (albeit less), see #864.

I'm going to take over and finish #865 to address.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Reinstate new device factory and its use for I22
3 participants