-
Notifications
You must be signed in to change notification settings - Fork 3
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
Question: How should a Consumer specify which action to query? #43
Comments
Good question. This answer is based on proposal #42 and my experience with hiveot. This currently works in hiveot. This also uses an ActionStatus type that http basic and the strawman proposal use (minor differences, same idea).
If the action request is not accepted then the ResponseMessage contains an error and no ActionStatus is created. ActionStatus: "id": "{ID of the action request; correlationID if the action was requested with the websocket protocol}",
"thingID": "{thingID to which the action affordance belongs}",
"name": "{name of the action affordance}",
"status": "{status of the action}",
"requested": "{timestamp of the request}",
"updated": "{timestamp the action status was last updated}",
"output": "{output when status is completed}",
"error": "{errer when status if failed}", This uses 'id', not 'correlationID' to uniquely identify the action. It can be the correlationID but the device can generate its own UUID, href, or whatever. It is just a string.
When sending a RequestMessage with operation 'queryaction', without an input this queries all running instances of the action with the name specified in RequestMessage. The ResponseMessage contains a list of ActionStatus objects of that action. If no actions are running this list contains a single ActionStatus instance of the last handled action.
If the RequestMessage input for the queryaction operation is provided it identifies the action to query. This must correspond to the 'id' field in the ActionStatus.
(ps: hiveot used its own RequestMessage/ResponseMessage but this is currently being reworked to proposal #42 including NotificationMessages. It already uses the above approach for actions. |
The result looks like this: queryaction without inputRequestMessage{
"correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
"messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
"messageType": "request",
"thingID": "https://mythingserver.com/things/mylamp1",
"operation": "queryaction",
"name": "fade",
} ResponseMessage{
"correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
"messageID": "c370da58-69ae-4e83-bb5a-12345",
"messageType": "response",
"operation": "queryaction",
"name": "fade",
"thingID": "https://mythingserver.com/things/mylamp1",
"output": [
{
"id": "action-id-12344",
"thingID": "https://mythingserver.com/things/mylamp1",
"name": "fade",
"status": "running",
"timeRequested": "2024-11-11T11:43:10.100Z",
"timeUpdated": "2024-11-11T11:43:10.101Z",
},
{
"id": "action-id-12345",
"thingID": "https://mythingserver.com/things/mylamp1",
"name": "fade",
"status": "pending",
"timeRequested": "2024-11-11T11:43:20.135Z",
"timeUpdated": "2024-11-11T11:43:20.136Z",
},
...
],
} |
queryaction for a specific instanceRequestMessage{
"correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
"messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
"messageType": "request",
"thingID": "https://mythingserver.com/things/mylamp1",
"operation": "queryaction",
"name": "fade",
"input": "action-id-12345"
} ResponseMessage{
"correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
"messageID": "c370da58-69ae-4e83-bb5a-12345",
"messageType": "response",
"operation": "queryaction",
"name": "fade",
"thingID": "https://mythingserver.com/things/mylamp1",
"output": [
{
"id": "action-id-12345",
"thingID": "https://mythingserver.com/things/mylamp1",
"name": "fade",
"status": "pending",
"timeRequested": "2024-11-11T11:43:20.135Z",
"timeUpdated": "2024-11-11T11:43:20.136Z",
},
...
],
} This always returns a list in the output for consistency. queryaction and queryallactions always return a list of requested action(s). |
@hspaay Thank you for the feedback. The fact that it's backed by implementation experience makes it particularly valuable.
If I've understood correctly this would mean having an I would suggest only using the term
FYI this is not really the current meaning of the
I think this is a good idea since it's clearer if there's only a single
Combining these suggestions with #42 we'd get something like the following examples...
|
1. Wrt invokeaction response
Hmm I might have misunderstood, earlier. Are you suggesting to wait with the response until the action is complete and send notifications to indicate progress? That makes a lot of sense. In that case I can also understand why the output is the actual action output and not an ActionStatus. If that is the intent then lets roll with that. I do still believe it is more consistent that the invokeaction notification contains the ActionStatus object as it reports on, well ... action status. That would also omit the need for a status field in the notification message. (are there any other uses for it?) 2. queryaction input
Yeah I can see how this got watered down. Isn't this up to the protocol binding though? TD-1.1 says "Identifies the querying operation on Action Affordances to get the status of the corresponding action." This leaves it quite open. Maybe best then to leave it as a future oppertunity to be more specific in querying actions by providing the actionID (actionRequestID) as the input parameter. It would be cleaner this way than adding another operation IMHO. 3. queryaction/queryallactions output formatYour example shows a queryaction responsemessage with status and actionRequestID members. The consistent use of ActionStatus in the response instead of blending this with the response itself is less confusing. Blending is in my opinion more confusing as the response is both a response to the queryaction request as well as the response of the queried action. A second point is that querying a single action can have multiple action results as actions can be queued or run in parallel. Assuming that this is still being considered. TD-1.1 is quite vague on this. You do point out that this isn't in the definition of queryaction but at the same time I don't see anything saying that you can't do this. Maybe best not to close this door? Third, it is more in line with 'queryallactions' which does return ActionStatus objects. Even if the decision is to only return a single action status it is still more consistent to use the ActionStatus instance. Fourth: It is the purpose of the ActionStatus instance to describe .. well the action status. The purpose of queryaction is to obtain the action status. It seems logical to use the ActionStatus instance in the result. Rather than needing a reason to use it there should be a reason for not using it when querying action status in all its variations. Fifth: This is more in line with http-basic which does return an ActionStatus object in async results. Not that I think http-basic is just a wonderful example, but in this case it works out well ;) This is why I propose to always use ActionStatus objects in response to queryaction/queryallactions and for action progress notifications. I do strongly suggest not to blend the action status and the response message. I have done this in an earlier iteration and it became more difficult to debug and follow what is going on, so I changed hiveot to separate action status into its own object in the output of response/notification messages. The separation of concerns was a bit of a relieve in testing and debugging as it made it clearer to know what you're looking at. This confirmed to me it was the right decision. If you prefer only a single ActionStatus in the output of queryaction then that works for me, so not a big deal. (it is what is currently happening in hiveot) 4. timeUpdated vs timeCompletedI wonder if it is better to use 'timeUpdated' instead of 'timeCompleted' in ActionStatus. The action might be running and provide intermediate progress updates. timeUpdated would indicate the time of the confirmed update, which for long running actions can indicate things are progressing. After completion this is the completion time. After cancellation this is the cancellation time. It also avoids the need to have all these different timestamps separately. 5. Using 'actionRequestID' (proposing 'actionID')Looks like we are on the same page that the action identification is best decoupled from the correlationID or messageID. An action be invoked through another protocol binding which uses another ID format. Its up to the action handler to choose the format. As far as naming is concerned, can I propose 'actionID' as a middle ground? using 'actionRequestID' suggests it is related to the request, which we just agreed it isn't :) 6. Proposed format for queryactionIf I merge our combined feedback and just use a single response in queryaction, it looks like this: RequestMessage{
"correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
"messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
"messageType": "request",
"thingID": "https://mythingserver.com/things/mylamp1",
"operation": "queryaction",
"name": "fade",
} ResponseMessage{
"correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
"messageID": "c370da58-69ae-4e83-bb5a-12345",
"messageType": "response",
"operation": "queryaction",
"name": "fade",
"thingID": "https://mythingserver.com/things/mylamp1",
"output": {
"actionID": "action-id-12344",
"thingID": "https://mythingserver.com/things/mylamp1",
"name": "fade",
"status": "running",
"timeRequested": "2024-11-11T11:43:10.100Z",
"timeUpdated": "2024-11-11T11:43:10.101Z",
}
} thingID and name in the response are optional. This goes for all responses as correlationID identifies the corresponding request. Are we on the same page with this? |
Yes.
I agree it would be more consistent with the
No, which is intentional since it's only relevant to queryable actions.
Yeah I guess it does if you squint, but there's still only one operation type. Currently WoT Profiles interprets this as querying an individual instance of an action rather than all instances of an action.
Maybe. What I was trying to avoid was a
I would like the interpretation of the
The terms However, I'm increasingly concerned that what we are defining here is a quasi-
I think you'll still want to know when an action was requested and when it was completed or failed.
Now we're just bikeshedding over names, which is a good sign ;) Actually I think it is related to the request, since what's important is what I think it's important to distinguish between an "action" (which is identified by a name like "fade") and an individual instance of an action (which has a unique ID like "239ae560-4c66-4e34-8aca-4d4241e70bad"). In the assertions of the WoT Profiles specification we call this an "action request". If that's confusing an alternative term might be "action instance", so But if the term is set to the message ID of the
I feel strongly that the What's missing from your example is the actual output of an action which would presumably mean having an Overall I think I agree with adding an ActionStatus object to {
"thingID": "https://mythingserver.com/things/mylamp1",
"messageID": "eecaba4e-3cf7-42be-9f58-808c164e127c",
"messageType": "response",
"operation": "queryaction",
"name": "fade",
"actionStatus": {
"status": "completed",
"output": true,
"actionRequestID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
"timeRequested": "2024-11-10T11:43:19.135Z",
"timeEnded": "2024-11-10T11:43:20.513Z"
}
"correlationID": "e99c78ce-d8b9-4fe8-aabc-5c74829abfe1"
} (or we use "status" and rename the other "status" member to something else, in Profiles as well). BTW the reason I'm so concerned about the Web Thing Protocol being consistent with WoT Profiles is that I hope there will be a WebSocket Profile at some point in the future which mandates use of the Web Thing Protocol WebSocket sub-protocol, and we aim for consistency between profiles. However, although WoT Profiles has existing implementations which makes changes more painful it's not a Recommendation yet, so it is still possible to make changes if we really need to. Certainly for WoT Profiles 2.0. |
In a
queryaction
operation, how should the Consumer specify which action to query?correlationID
to the correlation ID of theinvokeaction
request, but then how should the response to thequeryaction
request be correlated with thequeryaction
response if there are multiplequeryaction
requests?queryallactions
request to contain multiple correlation IDs to correspond to each action whose status is being reported?actionRequestID
member which corresponds to themessageID
orcorrelationID
of theinvokeaction
request, so that aqueryaction
operation can have a separatecorrelationID
for eachqueryaction
request, and a response to aqueryallactions
operation only needs to contain onecorrelationID
?The text was updated successfully, but these errors were encountered: