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

Sync client: interference from non-PVs on the network #775

Open
ZLLentz opened this issue Sep 10, 2021 · 1 comment
Open

Sync client: interference from non-PVs on the network #775

ZLLentz opened this issue Sep 10, 2021 · 1 comment
Labels

Comments

@ZLLentz
Copy link

ZLLentz commented Sep 10, 2021

Issue/Suggestion

In the sync client, we should ignore datagrams with bad command IDs while searching for PVs while making channels.

Currently, if you are creating a channel using the sync client and something besides an EPICS PV responds, an exception is raised instead of ignoring it and waiting for an EPICS PV to respond.

Context

I am currently using caproto to check the accuracy of my facility's EPICS gateways via brute-force checking ~3 million PVs, which is a great opportunity to find all of the race conditions and edge cases in everyone's code.

Occasionally my tests fail with this (snipped traceback from pytest failure):

/cds/home/k/klauer/miniforge3/envs/whatrecord/lib/python3.9/site-packages/caproto/sync/client.py:160: in make_channel
    address = search(pv_name, udp_sock, timeout)
/cds/home/k/klauer/miniforge3/envs/whatrecord/lib/python3.9/site-packages/caproto/sync/client.py:143: in search
    commands = b.recv(bytes_received, address)
/cds/home/k/klauer/miniforge3/envs/whatrecord/lib/python3.9/site-packages/caproto/_broadcaster.py:118: in recv
    commands = read_datagram(byteslike, address, self.their_role)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

data = b'\x00\x00\x00\x03\x00\xf8\xe2\x05\x00\x01\x00\x02\x80\x00\x00\x01\x00\x00\x00\x0f1Lw\xfc\x00\x00\x00\x07\x00\x00\x00\...0\x00\x00\x00\x00\x00\x00\x0050-0503328352\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
address = ('172.21.76.192', 3956), role = SERVER

    def read_datagram(data, address, role):
        "Parse bytes from one datagram into one or more commands."
        barray = bytearray(data)
        commands = []
        while barray:
            header = MessageHeader.from_buffer(barray)
            barray = barray[_MessageHeaderSize:]
            try:
                _class = Commands[role][header.command]
            except KeyError:
>               raise RemoteProtocolError(
                    f"Packet with bad command ID {hex(header.command)} was "
                    f"received. Header: {header}"
                ) from None
E               caproto._utils.RemoteProtocolError: Packet with bad command ID 0x416c was received. Header: MessageHeader(command=16748, payload_size=27753, data_type=25956, data_count=8278, parameter1=1769171311, parameter2=1847612517)

Which oddly enough is a packet received from a camera on the network that seems to be an identifier.

@tacaswell
Copy link
Collaborator

Can we make this configurable? I can see the case for being strict ("nothing else should be responding, if it is I need to find and sush that thing") and forgiving ("this is UDP anyone can scream at the wind!").

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

No branches or pull requests

3 participants