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

An idea... #642

Closed
wants to merge 1 commit into from
Closed

An idea... #642

wants to merge 1 commit into from

Conversation

coretl
Copy link
Collaborator

@coretl coretl commented Nov 8, 2024

In #641 we make connect in mock mode sync rather than async, but can't complete the job because Device.connect is async so child connects must also be async. This PR make connect return an optional Task which means we can make the mock path fully sync.

Too magic?

Also, tests need fixing...

@coretl coretl marked this pull request as draft November 8, 2024 14:32
@callumforrester
Copy link
Contributor

Mocking is always magic anyway so the magic does not bother me

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.

I feel like connect is a semi-user facing interface. For example, we use it quite a lot in dodal/mx_bluesky (which may be wrong I guess). This complicates the job for the caller quite a bit so I'm not a big fan. We could do something instead like:

class DeviceConnector:
    def connect_mock(self, device: Device, mock: LazyMock):
        # Connect serially, no errors to gather up as in mock mode
        for name, child_device in device.children():
            assert not child_device._mock_connect(mock=mock.child(name)) #Bit ugly this calls something private but I wouldn't want to confuse external callers of `Device`

class Device:
    ...

    def _mock_connect(self, mock):
        # Always connect in mock mode serially
        if isinstance(mock, LazyMock):
            # Use the provided mock
            self._mock = mock
        elif not self._mock:
            # Make one
            self._mock = LazyMock()
        self._connector.connect_mock(self, self._mock)

    async def connect(
        self,
        mock: bool | LazyMock = False,
        timeout: float = DEFAULT_TIMEOUT,
        force_reconnect: bool = False,
    ) -> None:
        """Connect self and all child Devices.

        Contains a timeout that gets propagated to child.connect methods.

        Parameters
        ----------
        mock:
            If True then use ``MockSignalBackend`` for all Signals
        timeout:
            Time to wait before failing with a TimeoutError.
        """
        if mock:
            self._mock_connect(mock)
        else:
            ...

@coretl
Copy link
Collaborator Author

coretl commented Nov 11, 2024

I think the gains are marginal, so let's abandon this idea

@coretl coretl closed this Nov 11, 2024
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.

3 participants