Subject: [core] Cancellation (was: I-D Action: draft-ietf-core-observe-12.txt)

From: Klaus Hartke <[email-masked]>
Date: Wed, 19 Feb 2014 20:25:52 +0100

> * A mechanism for the proactive cancellation of observations is now
> provided in addition to the existing "garbage collection" approach. It
> is OPTIONAL for clients and REQUIRED for servers.

For this cancellation mechanism, multiple proposals have been floating
around for a while:

- Sending a GET request to the same URI without an Observe option

- Sending a GET request to the same URI with some new Cancellation Option

- Sending a confirmable or non-confirmable message with a Code from an
unused range, such as 7.31

- Sending a confirmable or non-confirmable message with an unused
syntax, like an Empty (0.00) message with a payload

All of these proposals are somewhat suboptimal:

- In the first two ones, it's semantically weird for the client to ask
for a current representation of the resource state if it is already
being notified of new resource states and it now cancels the
observation because it is no longer interested in having a current
representation. Also, a cancellation request should be local to the
communication between the client and the next hop towards the origin
server, and should not force a whole chain of intermediaries to update
their caches just so the next hop can supply a current representation
to the client that the client actually does NOT want. Of course, we
could extend the GET method so it doesn't yield a current
representation of the target resource in some cases, but then the GET
method would become really difficult to explain. Cancellation is not a
request targeted at a resource like a GET or POST request; it's a
control message targeted at an ongoing conversation between the client
and the server.

- For the latter two ones, elements of CoAP come into use that are
currently unused. This may require changes somewhat larger to existing
implementations than the first two proposals, but would allow us to
express cancellation in a semantically clean way. There may be better
uses for these elements in the future, though, so I'm a bit reluctant
to bring one of them into use them now (in particular the 7.xx range
of codes).

Overall, I think the comparatively cleanest solution with the smallest
impact on existing implementations is the 7.31 code. So I've put that
into I-D.ietf-core-observe-12.

Best regards,
Klaus

---

From: Bert Greevenbosch <[email-masked]>
Date: Tue, 25 Feb 2014 02:10:51 +0000

Hi Klaus,

Thank you for updating the observe draft.

Thanks also for your explanation mail on the new cancellation mechanism in v12, section 3.6. See the complete quoted mail below, but here is the main snippet I want to comment on:

> For this cancellation mechanism, multiple proposals have been floating around for a while:
> ...
> - Sending a confirmable or non-confirmable message with a Code from an unused range, such as 7.31
> ...

Sending a 7.31 code would indeed be a solution for active cancellation of an observation relationship.

However, it seems to turn around the CoAP architecture, as normally the client sends GET/PUT/POST/DELETE Requests, as well as RSTs/ACKs to the server, whereas the server sends a Response with suitable x.yy Code.

Until now, these x.yy Codes were restricted to Responses. OMA LwM2M had a requirement for sending this kind of Request/Response pairs in two directions too, but they basically defined the LwM2M server to have both CoAP server and CoAP client functionality, and likewise for the LwM2M client.

In our observation case, I think the 7.31 message looks much like a Response, but without associated Request. If there was a Request, the RST mechanism could be used.

I think we need to consider deeply if the architectural turnaround of CoAP clients sending response like messages to the server is justified by the use case, especially since (as far as I know, please correct me if I am wrong!) no other CoRE documents allow a CoAP client to send a Response to a CoAP server.

I agree that sending a GET without Observe option to cancel the observation is semantically a bit weird. However, it does work, so why not keep it that way? A "cancel observation" option would be quite acceptable too, with that we omit the need to send a payload in the response.

What do you think?

Best regards,
Bert

---
> is OPTIONAL for clients and REQUIRED for servers.

For this cancellation mechanism, multiple proposals have been floating around for a while:

- Sending a confirmable or non-confirmable message with a Code from an unused range, such as 7.31

- Sending a confirmable or non-confirmable message with an unused syntax, like an Empty (0.00) message with a payload

- In the first two ones, it's semantically weird for the client to ask for a current representation of the resource state if it is already being notified of new resource states and it now cancels the observation because it is no longer interested in having a current representation. Also, a cancellation request should be local to the communication between the client and the next hop towards the origin server, and should not force a whole chain of intermediaries to update their caches just so the next hop can supply a current representation to the client that the client actually does NOT want. Of course, we could extend the GET method so it doesn't yield a current representation of the target resource in some cases, but then the GET method would become really difficult to explain. Cancellation is not a request targeted at a resource like a GET or POST request; it's a control message targeted at an ongoing conversation between the client and the server.

- For the latter two ones, elements of CoAP come into use that are currently unused. This may require changes somewhat larger to existing implementations than the first two proposals, but would allow us to express cancellation in a semantically clean way. There may be better uses for these elements in the future, though, so I'm a bit reluctant to bring one of them into use them now (in particular the 7.xx range of codes).

Overall, I think the comparatively cleanest solution with the smallest impact on existing implementations is the 7.31 code. So I've put that into I-D.ietf-core-observe-12.

Best regards,
Klaus

---

From: "FOSSATI, Thomas (Thomas)" <[email-masked]>
Date: Tue, 25 Feb 2014 07:24:59 +0000

Hi Bert,

the problem with using "GET + option” as a means to signal the
cancellation is that it subverts the semantics of the GET verb.

I understand your concern about introducing a new protocol element late in
the process, but the cancellation operation is really new semantics and as
such it deserves a new protocol element (IMO).

Maybe introducing a new method instead of the new code would solve your
"asymmetry” worry?

Cheers

On 25/02/2014 02:10, "Bert Greevenbosch" <[email-masked]>
wrote:
>Thanks also for your explanation mail on the new cancellation mechanism
>in v12, section 3.6. See the complete quoted mail below, but here is the
>main snippet I want to comment on:
>
>However, it seems to turn around the CoAP architecture, as normally the
>client sends GET/PUT/POST/DELETE Requests, as well as RSTs/ACKs to the
>server, whereas the server sends a Response with suitable x.yy Code.
>
>Until now, these x.yy Codes were restricted to Responses. OMA LwM2M had a
>requirement for sending this kind of Request/Response pairs in two
>directions too, but they basically defined the LwM2M server to have both
>CoAP server and CoAP client functionality, and likewise for the LwM2M
>client.
>
>In our observation case, I think the 7.31 message looks much like a
>Response, but without associated Request. If there was a Request, the RST
>mechanism could be used.
>
>I think we need to consider deeply if the architectural turnaround of
>CoAP clients sending response like messages to the server is justified by
>the use case, especially since (as far as I know, please correct me if I
>am wrong!) no other CoRE documents allow a CoAP client to send a Response
>to a CoAP server.
>
>I agree that sending a GET without Observe option to cancel the
>observation is semantically a bit weird. However, it does work, so why
>not keep it that way? A "cancel observation" option would be quite
>acceptable too, with that we omit the need to send a payload in the
>response.
>
>What do you think?
>
>Best regards,
>Bert
>
>---
>- Sending a confirmable or non-confirmable message with an unused syntax,
>like an Empty (0.00) message with a payload
>
>for a current representation of the resource state if it is already being
>notified of new resource states and it now cancels the observation
>because it is no longer interested in having a current representation.
>Also, a cancellation request should be local to the communication between
>the client and the next hop towards the origin server, and should not
>force a whole chain of intermediaries to update their caches just so the
>next hop can supply a current representation to the client that the
>client actually does NOT want. Of course, we could extend the GET method
>so it doesn't yield a current representation of the target resource in
>some cases, but then the GET method would become really difficult to
>explain. Cancellation is not a request targeted at a resource like a GET
>or POST request; it's a control message targeted at an ongoing
>conversation between the client and the server.
>
>uses for these elements in the future, though, so I'm a bit reluctant to
>bring one of them into use them now (in particular the 7.xx range of
>codes).
>

---

From: Carsten Bormann <[email-masked]>
Date: Tue, 25 Feb 2014 09:22:59 +0100

> Until now, these x.yy Codes were restricted to Responses. 

The cancellation is neither a request nor a response on the request/response layer, it is *about* a previously made, still active request (namely, canceling it).  Just as requests and responses are bound to each other using a token, the cancellation also is bound to the token.

So using a 0.xx (which is about genuine requests) code doesn’t seem right either.

Indeed, the choice of 7.xx for cancellation is somewhat arbitrary.  So far, a token for a message carrying a 0.xx code is one selected out of the sender’s name space, and tokens for messages carrying x.yy codes are selected out of the name space of the message receiver.  That would no longer be the case for 7.31.  But maybe that’s OK — the condition of the “sender’s token" rule would change to “0.xx or 7.31” or even “0.xx or 7.xx”*).

We can’t handle proactive cancellation at the message layer, because we need the token as the identifier of the active request.
(It works on the reactive side because the token in the response that is being rejected creates the link.)

So, if we want proactive cancellation, the choice is down to:

— using a side effect of one request (a GET without Observe) on another one (the active GET with Observe).  This requires some rules on when the side effect is actually exerted (e.g., using the concept of cache key).  There also is a constant danger of inadvertently triggering the side effect, which is why we aren’t using this choice any more.

— using the token reuse handling mechanism.  This still requires a new request, because we don’t have anything else a client can do with a token.  Doing another request to get rid of the active one doesn’t strike me as a particularly clean way (see Klaus’ scenarios).  But yes, on the server you already have to have some code to handle inadvertent token reuse, so that code can be reused.

— making cancellation explicit.  It might have seemed cleaner to use code 0.00 for that (think of an empty request replacing the active one on the token given), but we have started using that code for CoAP ping.  Note that explicit cancellation can also be used to cancel any other long-running request (“clean a token”) where the client no longer needs the answer, so this could be useful beyond -observe.

Of course, the fourth choice is not to have proactive cancellation in -observe, maybe adding it later separately.

Grüße, Carsten

*) (7.31 is a somewhat “exposed” code because DTLS messages coming in on a CoAP port look like “7.30” messages, at least for DTLS 1.x; DTLS 2.x will have “7.29” in this place etc.)