Subject: OCP: Getting Out Of The Loop optimization broken

From: Alex Rousskov <[email-masked]>
Date: Fri, 24 Oct 2003 23:51:39 -0600 (MDT)

Hi,

	I used to think that Wont-Use parameter is sufficient for a
callout server to get out of the loop safely. I now believe that it is
not true because Wont-Use can be used to tell the processor that
original data is no longer needed, but it does not tell the processor
that the service is not going to _generate_ more adapted data. I tried
to fix this logic in the new OCP Core section, quoted below.

Please see it I am still missing something important or if the
interface can be simplified again:

8. 'Out Of The Loop' Optimization

   Many services are applicable to a small percentage of application
   messages and yet have to see the beginning of every application
   message to decide on applicability (e.g., services that adapt based
   on declared or guessed MIME type). Many services adapt application
   message "headers" or "prefix" only and are not interested in the
   remaining parts of an application message (e.g., URL blocking and ad
   insertion services). 'Getting Out Of The Loop' optimization allows a
   callout server to get out of application message processing loop when
   the server is confident that it does not need to see remaining data.

   Two conditions are necessary for the callout server to get out of the
   loop nicely:

   No adaptation need: The callout server must finish its primary work.
      It should sent all adapted data to the processor and should
      require no more original data from the processor. Since
      adaptations and adaptation needs might not depend on original
      data, only the server can evaluate this condition.

   No copying need: The OPES processor must receive back all unpreserved
      data chunks that were sent to the callout server for adaptation.
      Note that data chunks that are not preserved and are not returned
      by the callout service would be lost. Since the server may not
      have seen all the original data sent, only the processor can
      evaluate this condition.

   Since no single agent can determine both conditions, the agents have
   to cooperate.  The service has to tell the processor when the first
   condition is true. This is done via the Want-Out message (XXX:
   document Want-Out). The processor has to tell the service that there
   are no pending unpreserved data chunks.  The latter is done by
   terminating the transaction with a 206 "Get Out" result (XXX:
   document 206). Between the above two conditions or messages, the
   callout server returns all original data unmodified back to the OPES
   processor, draining pending data queue (if any).

Thank you,

Alex.

---

From: "Martin Stecher" <[email-masked]>
Date: Sat, 25 Oct 2003 18:25:27 +0200

> interface can be simplified again:

I agree that a Want-Out message is very needed and it's a good idea to have
a special status code as result for transaction termination.

Question here: Should it be the result of TE or better AME? I think AME fits
better.
Should the callout server confirm by sending also a special (the same 206)
result code?

There are three normal cases for transaction termination. We may want to
discuss this together in one section of OCP core and define result codes for
all three. What do you think?

1. Complete application message is sent to callout server and terminated
with AME 200, callout server returns a complete message and also ends with
AME 200.

2. At some time callout server decides to only echo the rest of the message.
It sends a Want-Out message, echos all data until it receives an AME 206 and
then responds also with an AME 206.

3. The callout server sends a response (e.g. an error message for the
client). Sending is done before complete application message has been
received. The callout server will send its AME message and by design does
not longer care about DUM/DUY messages being transferred for this
transaction. OPES processor can stop sending the application data when it
sees the AME message. It will terminate the transaction.
We should also have a special 2xx result for this case, I think.

Note, that in cases 1 and 2 the OPES processor sends the AME message first
and in case 3 it's the callout server sending AME first.

Of course beside these three cases there are other scenarios, but I think
they all deal with transaction terminations due to error conditions.

Regards
Martin

---

From: Alex Rousskov <[email-masked]>
Date: Sat, 25 Oct 2003 20:01:32 -0600 (MDT)

On Sat, 25 Oct 2003, Martin Stecher wrote:

> I agree that a Want-Out message is very needed and it's a good idea
> to have a special status code as result for transaction termination.
>
> Question here: Should it be the result of TE or better AME? I think
> AME fits better.

I agree and will fix the current wording to imply "AME". The following
TE will have a "normal" 200 code.

However, please note that "I want out of the loop" has a transaction
scope, not application message scope. It is not possible to continue
the transaction once the server is out of the loop.

Proof by contradiction: If it were an application message-scoped
mechanism it would be possible to get one application message out of
the loop while still processing remaining application messages within
the same transaction as usual. The latter is only possible for
profiles that support multiple adapted AMs per single original AM
(e.g., SMTP). To support such a mode, the processor would have to
maintain at least two original data flows: one short-circuited due to
Want-Out and one to feed remaining adapted flows. That is probably too
much complexity and goes way beyond the current "one transaction, one
original data flow" approach.

> Should the callout server confirm by sending also a special (the
> same 206) result code?

Yes, I believe so. Both agents send AMEs/206 and TE/200. If the
callout server sends AME/200, it means the adapted application message
should stop at that point instead of being continued from the original
data flow (i.e, once processor gets AME/200, the loop is over).

In other words, "I want out of the loop" does not mean "I am not going
to adapt starting now". Imagine a situation where an overloaded
non-essential service wants to get out of the loop, but does not mind
keeping adaptation algorithms alive (or cannot disable them) and those
algorithms decide to terminate the message "early" for reasons
unrelated to the overload condition.

If you agree with the rationale, I should document the above caveat.

> There are three normal cases for transaction termination. We may
> want to discuss this together in one section of OCP core and define
> result codes for all three. What do you think?

> 1. Complete application message is sent to callout server and
> terminated with AME 200, callout server returns a complete message
> and also ends with AME 200.
>
> 2. At some time callout server decides to only echo the rest of the
> message. It sends a Want-Out message, echos all data until it
> receives an AME 206 and then responds also with an AME 206.
>
> 3. The callout server sends a response (e.g. an error message for
> the client). Sending is done before complete application message has
> been received. The callout server will send its AME message and by
> design does not longer care about DUM/DUY messages being transferred
> for this transaction. OPES processor can stop sending the
> application data when it sees the AME message. It will terminate the
> transaction.

In #3, the server will terminate the transaction first: it will send
TE right after AME.

> We should also have a special 2xx result for this case, I think.

Could you explain why a special 2xx result would be needed for #3?
To ease statistics collection? Requests, responses,
and short-circuiting is application specific. Do you propose to add
a special status code to HTTP Adaptations draft?

> Of course beside these three cases there are other scenarios, but I
> think they all deal with transaction terminations due to error
> conditions.

If I have time, I will enumerate the above scenarios in a informative
(non-normative) way.

I have a related question: Do you think a callout server may send AME
if it thinks that the message is completed (e.g., the original body
has been received and processed, and no trailers are expected)? Or
should the server wait for AME from the processor before sending its
own AME, under normal conditions? In other words, do we want to
support concurrent close optimization OR do we want to allow for
larger-than-expected messages to be adapted successfully? In yet other
words, what does constitute application message end (AME from the
other agent only OR that and some other information like AM-EL)?

Thanks,

Alex.

---

From: "Martin Stecher" <[email-masked]>
Date: Sun, 26 Oct 2003 19:41:50 +0100

> original data flow" approach.

Correct.
But in future we may have a message that could be sent between AME and TE,
maybe a message with which the OPES processor informs the callout service
about the shutdown procedure on the application message size.
In this case the callout server wants to get out of the loop for the
application
message but keeps the transaction alive until it receives the additional
meta info.

Therefore, as we already ageed upon, put the result code to AME and we are
better prepared for future extensions.

> data flow (i.e, once processor gets AME/200, the loop is over).

Agreed.

> In #3, the server will terminate the transaction first: it will send

For SMTP maybe not immediatly. See below.

> a special status code to HTTP Adaptations draft?

For HTTP this special code is not needed for direct functionality but for
better statisticy and debugging possibilities:
If the OPES processor wants to count for cases #3 a special result code
will even count then for the case in which both AMEs are sent
simultaniously.
If in a debugging session someone checks the data sent by the OPES
processor (not seeing the data sent by the callout server), he may wonder
that
an application message is not sent completly.
A result code other than 200 with the AME message, will help to understand
why.

For other application protocols, such as SMTP, the special code sent by the
callout service can even make functional sense.
A service may want to send several error messages, all not longer depending
on
the rest of the application data, to multiple recipient and therefore it
will send
several application messages. By indicating with the first AME that the OPES
processor can stop sending more application data it helps to increase
performance.
This case will be different from an error message which is sent in the first
application message but another application message which builds on the
complete
original message will follow; in that case, the callout server will send a
result 200
with the first AME.

If you agree in all this, I would prefer to have some general status codes
for the
three cases in OCP core.

> other agent only OR that and some other information like AM-EL)?

Simulatanious AMEs are possible as you discribe but I would like to
discourage their usage.
Implementations that want to have max performance can probably add
the AME and TE messages to the same TCP frame that contains the
last DUM in most cases (unless the few bytes for AME/TE do not fit).
In this case we have no extra waiting after the last DUM message has
been received and there is no need for clever counting which may sometimes
lead to problems.
The length of an application message SHOULD only be determined by the
length of the DUM message's payload (and the DUY message's size param)
and terminated by the AME message. AM-EL values are important for better
HTTP adaption but they SHOULD NOT be used for message length counting
for OCP purposes, IMO.

Regards
Martin

---

From: Alex Rousskov <[email-masked]>
Date: Sun, 26 Oct 2003 14:30:53 -0700 (MST)

On Sun, 26 Oct 2003, Martin Stecher wrote:

> > > want to discuss this together in one section of OCP core and
> > > define result codes for all three. What do you think?
> >
> > > terminated with AME 200, callout server returns a complete
> > > message and also ends with AME 200.
> > >
> > > 2. At some time callout server decides to only echo the rest of
> > > the message. It sends a Want-Out message, echos all data until
> > > it receives an AME 206 and then responds also with an AME 206.
> > >
> > > 3. The callout server sends a response (e.g. an error message
> > > for the client). Sending is done before complete application
> > > message has been received. The callout server will send its AME
> > > message and by design does not longer care about DUM/DUY
> > > messages being transferred for this transaction. OPES processor
> > > can stop sending the application data when it sees the AME
> > > message. It will terminate the transaction.
> >
> > In #3, the server will terminate the transaction first: it will
> > send TE right after AME.
>

Yes, I assumed single adapted AM above.

> For HTTP this special code is not needed for direct functionality
> but for better statisticy and debugging possibilities: If the OPES
> processor wants to count for cases #3 a special result code will
> even count then for the case in which both AMEs are sent
> simultaniously. If in a debugging session someone checks the data
> sent by the OPES processor (not seeing the data sent by the callout
> server), he may wonder that an application message is not sent
> completly. A result code other than 200 with the AME message, will
> help to understand why.

Agreed.

> For other application protocols, such as SMTP, the special code sent
> by the callout service can even make functional sense. A service may
> want to send several error messages, all not longer depending on the
> rest of the application data, to multiple recipient and therefore it
> will send several application messages. By indicating with the first
> AME that the OPES processor can stop sending more application data
> it helps to increase performance.

It looks like you want one adapted AME status code affect behavior of
other adapted application messages (whether they are going to receive
more original data). I think a better interface would be to have a
special "Wont-Use" message with a transaction scope, to indicate that
more original data is not needed. Hmm... It looks like we really do
not have a good enough interface to control original data flow in the
case of multiple adapted messages. It is currently not clear whether a
single adapted flow statement like Wont-Use parameter applies to
original data flow (and hence affects other adapted messages) or just
to the adapted flow making a statement. If we ever end up supporting
multiple adapted application messages, we would have to make all of
that clear and consistent.

For now, it looks like we assume that there is always a single
original flow, regardless of the number of adapted flows. Perhaps it
is the right decision (because it is simple), but it is hard to say
without digging into SMTP specifics. On the other hand, we stick
parameters like Wont-Use into am-id-dependent messages as if we imply
that two adapted flows may have different Wont-Use statements.

Do you think we should move all parameters that apply to the original
flow from am-id-specific messages to xid-specific messages? For
consistency reasons? Or do you think we will eventually require
processor to merge all such parameters together before deciding what
to do with the original flow? In other words, who is responsible for
merging adapted flows' interests into one statement affecting original
flow, the server or the processor?

> This case will be different from an error message which is sent in
> the first application message but another application message which
> builds on the complete original message will follow; in that case,
> the callout server will send a result 200 with the first AME.

Agreed.

> for the three cases in OCP core.

I think I can and should document 206 code in Core.

However, I am not sure how to document the "short circuit" code in the
Core. The Core cannot assume that an application protocol has
requests/responses and, hence, cannot document something like a
"Respond with this response instead of forwarding original request"
code.

If I try to be generic and document the code as something like
"adapted message is not intended for the original message recipient",
we might raise red flags for those who think that IAB "OPES must not
resolve URIs" concern applies in this case.

Suggestions?

Also, should we use 207 as the value for this short-circuit code? Or
does some HTTP extension use that code? We do not have to avoid all
conflicts with HTTP, but it would be nice to avoid same codes naming
very different things.

> The length of an application message SHOULD only be determined by
> the length of the DUM message's payload (and the DUY message's size
> param) and terminated by the AME message. AM-EL values are important
> for better HTTP adaption but they SHOULD NOT be used for message
> length counting for OCP purposes, IMO.

I agree in principle, and we already have a MUST that instructs agents
to send AMEs immediately.

Alex.

---

From: "Martin Stecher" <[email-masked]>
Date: Mon, 27 Oct 2003 00:40:11 +0100

> more original data is not needed.

Here is the new message. I found it :-)

> Hmm... It looks like we really do
> consistency reasons?

Yes, it makes a lot of sense.
Please introduce Wont-Send message and remove the parameter from DUM/DUY.

>Or do you think we will eventually require
> to do with the original flow?

Will be a night-mare and probably end with interop-problems as expectations
at OPES processor side will probably be too easy.

>In other words, who is responsible for

If a server thinks, it must create multiple messages and wants to use
Wont-Send
information it is responsible to get this done correctly.

> resolve URIs" concern applies in this case.

I do not see that you have to document a generic short-circuit thing.
In OCP core it is simply about receiving application messages back from the
service that are (not longer) depending on the original message.

Sending HTTP error messages in REQMOD is a prominent example and
real request satisfaction another but there are more examples, even for
RESPMOD and in real life:

1. Removing animations from GIF images are possible by changing few bytes
in the beginning of the image and the cropping the image data after the
first
picture. A callout service can return such adapted GIF and instruct the OPES
processor that it finished filtering even before it has seen the rest of the
GIF.
Further transmission is not necessary.

2. Very similar from AntiVirus area: There are BMPs known to contain
malicious
code after the real image data. A security service could delete them and use
the
207 result for best performance.

Do you now think, you can document that feature in core?

Martin

---

From: Alex Rousskov <[email-masked]>
Date: Sun, 26 Oct 2003 20:01:25 -0700 (MST)

> Please introduce Wont-Send message and remove the parameter from DUM/DUY.

Will do.

Alex.

---

From: Alex Rousskov <[email-masked]>
Date: Sun, 26 Oct 2003 20:10:16 -0700 (MST)

On Mon, 27 Oct 2003, Martin Stecher wrote:

> > However, I am not sure how to document the "short circuit" code in
> > the Core. The Core cannot assume that an application protocol has
> > "Respond with this response instead of forwarding original
> > request" code.
> >
> > "adapted message is not intended for the original message
> > recipient", we might raise red flags for those who think that IAB
> > "OPES must not resolve URIs" concern applies in this case.
> >
> > Suggestions?
>
> I do not see that you have to document a generic short-circuit
> thing. In OCP core it is simply about receiving application messages
> back from the service that are (not longer) depending on the
> original message.

A "no longer depending on (derived from?) the original" seems too
vague to me. Even in your examples, you have cases (non-animated GIF
and garbage-free BMP) that hardly fit this category because those
adapted objects are derived directly from the original ones. I cannot
think of a rule that will tell implementors exactly when to use 207
response code.

It may help if you can give two _similar_ examples: one with 200 code
and one with 207. Or, perhaps you can propose a better 207 code
definition/rule?

> real request satisfaction another but there are more examples, even
> for RESPMOD and in real life:
>
> 1. Removing animations from GIF images are possible by changing few
> bytes in the beginning of the image and the cropping the image data
> after the first picture. A callout service can return such adapted
> GIF and instruct the OPES processor that it finished filtering even
> before it has seen the rest of the GIF. Further transmission is not
> necessary.

Why not return a 200 OK status code in this case?

> malicious code after the real image data. A security service could
> delete them and use the 207 result for best performance.

Why not return a 200 OK status code in this case? What are the
performance differences that you are implying above? My understanding
is that a regular 200 OK response will result in appropriate
truncation of the forwarded image. 200 OK does not imply that the
adapted length is the same as original length, does it?

> Do you now think, you can document that feature in core?

Sorry, I need to better understand how is 207 different from 200
first. Please see the questions above.

Alex.