pymeasure / leco-protocol

Design notes for a generic communication protocol to control experiments and measurement hardware
https://leco-laboratory-experiment-control-protocol.readthedocs.io
MIT License
6 stars 3 forks source link

Message layer encoding added. #54

Closed BenediktBurger closed 1 year ago

BenediktBurger commented 1 year ago

Adds a few lines about the message layer encoding, see #43

Open questions:

Reasoning for several frames with RPC requests: According to JSON-RPC, all requests in a batch may be executed simultaneously and in any order. Therefore, if you want to measure the results of an action, you have to send to JSON-RPC requests, one after the other. If we allow more than one frame with those request objects (or batches thereof), we could stipulate, that the frames have to be executed in order.

It's an abstract idea, but maybe you deem it useful.

BenediktBurger commented 1 year ago

I experimented a little bit:

It is easy to implement, that all actions are done as procedure calls, even sign in etc.

bilderbuchi commented 1 year ago

Looks straightforward enough/OK, but I'm not sure if I have the complete picture, happy for others to weigh in!

bilderbuchi commented 1 year ago

I experimented a little bit:

It is easy to implement, that all actions are done as procedure calls, even sign in etc.

That's a relief to hear!

BenediktBurger commented 1 year ago

It's working very well. The jsonrpc makes the handling easy, as we do not have to define all those data fields and formats etc.

@bklebel , what do you think?

bklebel commented 1 year ago

It sounds quite reasonable to me, and in general json-rpc looks fitting (not sure I stated that already somewhere else).

Regarding multiple frames, which should then be executed in order, although I think it might be nice to have that possibility, for the setup we have in the lab I am not too sure whether we would use it. If we need something to happen in a specific order, it typically involves more than one device, and therefore more than one Component. For a Director to advance the overall sequence, it should get an acknowledgement for the action it just requested. I can imagine that others have other requirements in their setups, and there might be commands which are so simple and reliable that they cannot fail, however what comes to my mind is a series of frames with consecutive requests/commands, where one in the middle fails - what should the Component do in that case? Do we need to define that if we allow for such multi-frame/multi-batch commands/requests? Do we require an answer with the same amount of frames, even though some might be empty since we do not get/expect a return value? How did you deal with that so far @bmoneke?

BenediktBurger commented 1 year ago

In my "old" protocol I allowed a sequence of commands, but I never used it.

When I created the PR, I saw this possibility and wanted to offer it. One useful sequence would be to set some value / execute some command and in a second step to read some parameter to ensure, that the command did, what it was supposed to do (e.g. setting some power supply output voltage and then reading that voltage).

I see your point regarding what to do, if an error happens in the middle.

If it raises more problems than it solves, we can drop that idea.

bklebel commented 1 year ago

When I created the PR, I saw this possibility and wanted to offer it. One useful sequence would be to set some value / execute some command and in a second step to read some parameter to ensure, that the command did, what it was supposed to do (e.g. setting some power supply output voltage and then reading that voltage).

Okay, well, this is a good example - I would have put that into one action by the Component though. Essentially this is the same as what I thought of, just separated out into two requests, which I would have put into one.

Basically this leads to a more general question: Do we (always) require Components to acknowledge messages, technically and/or content-wise? I am quite unsure about that - I started off completely without it, later realised I needed it in some cases, went all the way of doing it every time, but now realise that for some applications speed might be more valuable than this kind of reliability. If we do not require acknowledgements based on these single-frames, then I think the multi-frame message approach would be important, as this would be only way (except for waiting really long, which we want to avoid) to ensure that the check we want to perform really happens only after the change we first request (one message might overtake another on the network in some edge cases, I guess). For this, we could restrict this to one- or two-frame messages, where the two-frame messages are reserved for acknowledgement-requests. Like this, we do not have a problem if the first message produces an error, because the subsequent request is only ever a request for data, which will then show that the first message "failed".

Also, if the Component has an internal exception and stops working through the messages, in the end we just do not get the data, and will be asking again, ideally before trying to tell the Component to try and repeat the action which was first requested.

BenediktBurger commented 1 year ago

Basically this leads to a more general question: Do we (always) require Components to acknowledge messages, technically and/or content-wise?

jsonrpc allows a user to specify during a request, whether he wants a response ("id" is not null) or not ("id" is null). That gives us (and our users) the flexibility to request a response, if we want one, and to forego a response, if we do not need it. Some requests should always require a response (e.g. reading some property), but that is the user's responsibility.

For this, we could restrict this to one- or two-frame messages, where the two-frame messages are reserved for acknowledgement-requests.

Similarly to above, I see it in the user's responsibility, if he sends more than one request (we should not forget, that jronrpc allows more than one command in a single message, but all commands might be executed in any order!) to make sure, that errors are handled properly. Nobody is forced to use a combined message, if they deem it dangerous.

The most important backdraw (regarding the protocol specification) is, that all Components have to iterate through all frames instead of looking at the first frame only.

bklebel commented 1 year ago

Ok, I forgot that from reading the jsonrpc specs, it sounds good to me to leave that to a user to decide.

The most important backdraw (regarding the protocol specification) is, that all Components have to iterate through all frames instead of looking at the first frame only.

I don't quite understand what you want to say with that, please elaborate on it

BenediktBurger commented 1 year ago

The most important backdraw (regarding the protocol specification) is, that all Components have to iterate through all frames instead of looking at the first frame only.

If we allow more than one frame with commands, then all Components have to iterate through all frames, i.e. they have to implement a loop. If we allow just a single frame with commands, the Components do not have to implement that loop.

An alternative could be, that our "message type" indicator can contain "single json" (obligatory to implement for LECO compliance), "multi json" (more than one json frame), and possibly binary or user defined types.

bilderbuchi commented 1 year ago

If we allow just a single frame with commands, the Components do not have to implement that loop.

In the spirit of limiting complexity, and avoiding getting bogged down to much with things to decide/flesh out, may I suggest that we err on the side of strictness/fewest features first. This is easier to extend later (e.g. in a v2 of LECO), compared to adding restrictions afterwards. Then, when the protocol has seen some use and we collected experience, we are in a better place to judge the trade-offs for the more flexible variants.

I.e., here maybe just allow single frames for now, and relax that later when we know more.

BenediktBurger commented 1 year ago

I agree with @bilderbuchi .

So we merge?

bklebel commented 1 year ago

With #55 resolved, I would agree with @bmoneke, we can merge this.