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

Add subscribeallevents and unsubscribeallevents operations #1082

Closed
benfrancis opened this issue Mar 29, 2021 · 8 comments
Closed

Add subscribeallevents and unsubscribeallevents operations #1082

benfrancis opened this issue Mar 29, 2021 · 8 comments

Comments

@benfrancis
Copy link
Member

benfrancis commented Mar 29, 2021

In #133 we discussed how the current wot-discovery draft provides an example Thing Description for the Directory Service API which combines three different event types (created_td, updated_td and deleted_td) into a single registration event such that a consumer can subscribe and unsubscribe to all three events at once.

This feels like a workaround for a missing feature in the Thing Description specification which enables consumers to subscribe to all events or unsubscribe from all events in a single operation. I would therefore like to propose new subscribeallevents and unsubscribeallevents operations to fulfill this requirement.

I suggest these should be form operations which can be used on a top level form, similar to how readallproperties and writeallproperties currently works.

{
    "@context": "http://www.w3.org/ns/td",
    "id": "urn:dev:ops:32473-WoTLamp-1234",
    "title": "MyLampThing",
    "securityDefinitions": {
        "basic_sc": {"scheme": "basic", "in": "header"}
    },
    "security": "basic_sc",
    "properties": {
        "on": {
            "type": "boolean",
            "forms": [{"href": "https://mylamp.example.com/properties/on"}]
        },
        "level": {
            "type": "number",
            "min": "0",
            "max": "100",
            "forms": [{"href": "https://mylamp.example.com/properties/on"}]
        }
    },
    "actions": {
        "toggle": {
            "forms": [{"href": "https://mylamp.example.com/actions/toggle"}]
        }
    },
    "events":{
        "overheated":{
            "forms": [{
                "href": "https://mylamp.example.com/events/overheated",
                "subprotocol": "longpoll"
            }]
        },
        "surge":{
            "forms": [{
                "href": "https://mylamp.example.com/events/surge",
                "subprotocol": "longpoll"
            }]
        }
    },
    "forms": [{
        "op": "readallproperties",
        "href": "https://mylamp.example.com/properties"
    }, {
        "op": "writeallproperties",
        "href": "https://mylamp.example.com/properties"
    },
    {
        "op": "subscribeallevents",
        "href": "https://mylamp.example.com/events",
        "subprotocol": "longpoll"
    },
    {
        "op": "unsubscribeallevents",
        "href": "https://mylamp.example.com/events",
        "subprotocol": "longpoll"
    }]
}

There would need to be some normative statements in the specification like there currently is for readallproperties and writeallproperties which describe what the payload for such resources should look like (i.e. a concatenation of the individual event interaction payloads, keyed by event name e.g. including the name of the event in the event payload). (See comment below).

See also: This is related to the readallpastevents operation proposed in #892 (comment) for event logs.

@egekorkan
Copy link
Contributor

Just for precision, when the subscribeallevents has succesfully executed, does the Consumer get all the events' data even if one event has happened or only the event that has happened? For comparison, in observeallproperties the Consumer gets all property values even if only one property value changes.

Another point, when I am subscribed to a single event and then execute unsubscribeallevents should I be unsubscribed from that single one as well? Or unsubscribeallevents is simply the opposite of subscribeallevents, i.e. it is executable only if the Consumer did subscribeallevents before doing that?

@benfrancis
Copy link
Member Author

benfrancis commented Mar 29, 2021

@egekorkan

Just for precision, when the subscribeallevents has succesfully executed, does the Consumer get all the events' data even if one event has happened or only the event that has happened? For comparison, in observeallproperties the Consumer gets all property values even if only one property value changes.

Good question. Actually it probably makes more sense to just receive individual events as they are emitted, because it's not clear what data would be provided for the other event types in that payload. I didn't know that's how observeallproperties worked, but in that case it's at least clear that the current value of all properties could be returned. If the expectation is in fact that events would be sent individually then the normative statements about the format of the payload are probably not necessary. (If there was a subscribemultiplevents/unsubscribemultiplevents then there may be a need to define the payload for subscribing, but I'm not sure we should add those since there has been some discussion about dropping readmultipleproperties and writemultipleproperties due to lack of use).

Another point, when I am subscribed to a single event and then execute unsubscribeallevents should I be unsubscribed from that single one as well? Or unsubscribeallevents is simply the opposite of subscribeallevents, i.e. it is executable only if the Consumer did subscribeallevents before doing that?

I would assume the former, since otherwise unsubscribeallevents would not do as its name implies.

Some of these details may require some prototyping in different protocols (e.g. SSE, WebSockets, longpoll, webhooks) to iron out because we may come up against limitations in certain protocols.

@benfrancis
Copy link
Member Author

benfrancis commented Mar 29, 2021

If the expectation is in fact that events would be sent individually then the normative statements about the format of the payload are probably not necessary

Actually, you might still need to define a way to include the name of the event in the event payload (e.g. wrap the event in an object, keyed by event name), since otherwise the consumer might not know to which type the event belongs.

@egekorkan
Copy link
Contributor

@benfrancis wrote:

Actually, you might still need to define a way to include the name of the event in the event payload (e.g. wrap the event in an object, keyed by event name), since otherwise the consumer might not know two which type the event belongs.

I agree that this kind of a payload scheme is needed.

Thank you for clearing up the other points. Regarding observeallproperties I am writing an issue since actually it does not make sense to return all property values, the consumer would need to understand which one has changed and there would be a logical difference between observable properties and events (which are almost the same thing).

@relu91
Copy link
Member

relu91 commented Mar 29, 2021

About the payload, I think we should prescribe a particular contentType for those all/multple operations... at least one contentType that is representable with a DataSchema. Not a big deal for events cause I think 99% of them would be serialized as json/xml. But what will happen when I try to read all properties and one of them is a video?

In general, those operations feel quite tight up to the specific protocol in use. What do you think?

@egekorkan
Copy link
Contributor

Not a big deal for events cause I think 99% of them would be serialized as json/xml. But what will happen when I try to read all properties and one of them is a video?

I think we need an explanation at least. Also having 9 photo properties and 1 JSON is possible :)

So the main reason these were added at the time was that there were APIs that supported this and we had no way of describing them properly. I think it was @mlagally 's contribution thus I think it is best to ask him. @mlagally how does the Oracle API behave when there are properties that are not of the same type as the others or are they always the same type?

@benfrancis
Copy link
Member Author

benfrancis commented Jul 13, 2021

I've submitted a pull request for this in #1191.

Regarding the event payload data schema, my conclusion is that this will need to be protocol specific. A couple of examples:

Server Sent Events

The data stream format for Server Sent Events defines its own mechanism for serialising the names of named events.

E.g. An overheated event defined a Thing Description as follows...

    "events": {
      "overheated": {
        "data": {
          "type": "number"
        },
      }
    }

...could be serialised with the event name in the event field and event data in the data field:

event: overheated
data: 101

WebSockets

WebSockets on the other hand do not have such a mechanism, so this would need to be defined in a sub-protocol.

E.g. the event could be serialised in JSON with the event name and data as properties of an object:

{
  "messageType": "event",
  "eventName": "overheated",
  "data": 101
}

For the Core Profile in the WoT Profile specification I'm going to propose that the Sever Sent Events example be used, and this serialisation can be defined in the protocol binding section of the profile.

@relu91
Copy link
Member

relu91 commented Jul 13, 2021

Regarding the event payload data schema, my conclusion is that this will need to be protocol specific

+1

I've submitted a pull request for this in #1082.

For the record, the PR is #1191

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

No branches or pull requests

3 participants