Subject: RE: OPES protocol, pre-draft

From: "Martin Stecher" <[email-masked]>
Date: Fri, 21 Feb 2003 12:20:22 +0100

Hi Alex, hi all,

> [...]
> 
> Client-server abstraction is OK when working on high-level and
> treating each application message as a size-less blob of information:
> [...]
> Once we start looking at the implementation level, the above becomes
> very inefficient both because of the resources spend keeping all the
> state and because of the introduced delays. This traditional approach
> does not scale with the message size. ICAP tries to solve the problem
> with the "preview" feature, but that solution is partial and rigid. To
> get rid of large buffers and staging delays one must use a pipeline
> approach:
> [...]
> Since most of the actions are performed on small chunks and in
> parallel, the buffering requirements are minimal and so is the extra
> delay. Response time overhead of a good OPES implementation should not
> exceed that of a [second] proxy overhead.
> 

ICAP/1.0 is already pipelined, I think. Messages are sent in chunked
transfer encoding. ICAP clients send chunk N before waiting for the
modified chunk N-1 to return.

The important advantage of your protocol outline is that due to the
introduction of xid and amid, it gets possible to implement the
multiple preview feature even without waiting for a decision from
the callout server before continueing.
It is a full multiplex, asynchronous pipeline approach.
No need to say: "I need more data"
Easy to say: "I am done with this amid, as soon as you are able to
go to the next application message, please do so"
No "out-of-sync" problem

I like this very much!

Let me add two example here to show the difference between a classic
approach and this one. Maybe it helps somebody as it helped me:

Example 1:
Callout server analyzes beginning of application message and detects
that it wants to see and modify the complete application message:

A. Traditional approach, ICAP/1.0 like with multiple preview
    0. C: Start of app. message 1
    1. C: Here is preview chunk 1
    2.                                S: Need another preview chunk
    3. C: Here is preview chunk 2
    4.                                S: OK. I take all the rest
    5. C: Chunk 3 of data
    6. C: Chunk 4 of data             S: mod. Chunks 1-3 of data
    7. C: Chunk 5 of data             S: mod. Chunk 4 of data
    8. C: End of data                 S: mod. Chunk 5 of data
    9.                                S: End of data
   10. C: Start of app. message 2

B. Proposed OPES protocol
    0. C: Start of app. message 1
    1. C: Chunk 1 of data             S: Start of app. message 1
    2. C: Chunk 2 of data            
    3. C: Chunk 3 of data             S: mod. Chunk 1-2 of data
    4. C: Chunk 4 of data             S: mod. Chunk 3 of data
    5. C: Chunk 5 of data             S: mod. Chunk 4 of data
    6. C: End of data                 S: mod. Chunk 5 of data
    7. C: Start of app. message 2     S: End of data
   
So B has no waiting cycles before forwarding next chunks of
data.

But how does this change if the callout server decides after
a second preview chunk that it is not interested in that data
and wants the OPES processor to handle the (rest) of the file
without forwarding it?

Example 2:
Callout server analyzes beginning of application message and detects
that it is not interested in this app. message:

A. Traditional approach, ICAP/1.0 like with multiple preview
    0. C: Start of app. message 1
    1. C: Here is preview chunk 1
    2.                                S: Need another preview chunk
    3. C: Here is preview chunk 2
    4.                                S: Not interested (204 resp.)
    5. C: Start of app. message 2

B. Proposed OPES protocol
    0. C: Start of app. message 1
    1. C: Chunk 1 of data             S: Start of app. message 1
    2. C: Chunk 2 of data            
    3. C: Chunk 3 of data             S: Not interested
    4. C: Chunk 4 of data             
    5. C: Start of app. message 2

In this case B sent more data and data chunks 3 and 4 will be ignored
by the callout server. It receives data for an application message it
is not (longer) working on.
But due to amid which is send with all data packets too (not shown
in the samples above) there is no danger to get out-of-sync.

---

From: Alex Rousskov <[email-masked]>
Date: Fri, 21 Feb 2003 09:17:37 -0700 (MST)

> modified chunk N-1 to return.

You are right, of course. I should have mentioned that ICAP does use
pipelining. IIRC, ICAP pipes start only after message headers and do
not allow any non-data messages to be present in-between (which forces
ICAP to use a chunk-extension hack to indicate end-of-data).

Another ICAP pipes disadvantage is that they cannot eliminate
callout-to-processor data flow when the callout processor did not
modify the data. The proposed protocol allows for this important
common-case optimization using "data-asis" messages.

Finally, ICAP pipes place ICAP connections in direct dependence on
HTTP connections. If I have to process 5 HTTP messages _concurrently_,
I have to open 5 ICAP connections. With the proposed approach, I can
use 1, 2, 3, 4, or 5 OPES connections. This allows for possibly
important performance optimizations on high-traffic servers.

These limitations of ICAP model apparently come from it being an
extension to HTTP (rather than being implemented on top of HTTP).
OPES pipes are not an optimization add-on but a design feature.

It remains to be seen if the proposed protocol is so much better that
it actually makes sense to phase out a working/deployed ICAP protocol.

Alex.