Re: Abstract Model contribution for module processing and also for attachments

Hi, Marc.  Here's some thoughts on your questions.

"Marc J. Hadley" wrote:

> This looks like a good start, I have a few questions and comments that
> are interspersed in the text below and preceded by [MJH].
>
>      An Abstract Model for Module Processing
>
>      Concepts
>
>        1. An XML Protocol Message consists of one or more blocks.
>
>           [MJH] Do we need to differentiate between the "body" of
>           the message and blocks targetted at module processors
>           (or XML Protocol Handlers to use the naming in the
>           current abstract model document) ? We could just treat
>           the message body as a special case of a block that is
>           targetted at the final module processor ?
>
>      There was some discussion in Boston as to whether we really
>      need any distinction between header and body blocks.  I
>      don't really see that we do yet.  Maybe they are all just
>      blocks.
>
>        1. The XML Protocol Message specifies a set of module
>           applications and the order in which they will be
>           carried out by the processor.  The message may also
>           specify a set of RPC conventions that influence the
>           module application.
>           [MJH] This is impacted by the ongoing discussion of the
>           routing capabilities of XML Protocol. If explicit
>           routing and targetting are supported (i.e. this XMLP
>           Handler at this XMLP Node - again using the naming in
>           the abstract model document) then there should be no
>           problem, although the order might result in one Node
>           being visited multiple times. If hop-by-hop routing
>           (i.e. each XMLP processor forwards messages according
>           to some internal rules or configuration) is supported
>           then the order of processing could only be guaranteed
>           if all Handlers are located on the same node.
>
>           Consider the following example: the message contains 3
>           blocks targetted at Handlers A, B and C in that order.
>           A and C are located at node 1 whilst B is located at
>           node 2.
>           Using explicit routing the message would be processed
>           in the following order: A[1], B[2], C[1].
>           Using hop-by-hop routing the message would be processed
>           in the following order: A[1], C[1], B[2].
>           Note that the order of processing is only important in
>           the case where Handlers are composed. Personally I
>           would prefer the KISS approach of hop-by-hop routing
>           and leave it up to the application designer to ensure
>           that order critical Handlers are co-located.
>
>      If  'seq { A(block-A), B(block-B), C(block-C) }' was the
>      specification, then it could only be honored by executing
>      A[1], B2[1], and then C[1] -- another visit back to node 1.
>      If 'par { A(block-A), B(block-B), C(block-C) }' was the
>      specification, then you would get  {A[1],C[1]},B[2] -- A[1]
>      or C[1] would be executing in parallel (conceptually at
>      least).  If they were reporting results, then the result
>      order would depend on which one (nondeterministically) was
>      allowed to serialize its result first. You could add another
>      semantic serialization rule that said that lexical order was
>      the result serialization order.
>
>      It seems to me that routing should be coordinated with the
>      semantics of the message, possibly even dictated by the
>      semantics of the message.  For composition, e.g., M1(M2(A)),
>      you really have to go to some node that processes M2 first
>      and then go to the node that does M1 (if it isn't the same
>      node).  Either the application has been explicitly
>      constructed to understand the connection, or you could have
>      a procedure that could dynamically configure routing paths,
>      given a processing specification and a node/module mapping.
>      The latter should be clever in attempting to minimize hops
>      using a fairly straightforward dependency graph, although
>      there will still be some tradeoffs.  Should some parallelism
>      be delayed since we will eventually have to go to that node
>      in a sequence anyway ...
>
>        1. A module application may result in a fault or a
>           successful evaluation.
>        2. The result of a successful evaluation may be void or a
>           response block.
>           [MJH] Does this imply that processed blocks are removed
>           from the message ? Should this be stated explicitly as
>           in section 4.2.2 of the SOAP 1.1 specification: "... a
>           recipient receiving a header element MUST NOT forward
>           that header element to the next application in the SOAP
>           message path". As in SOAP, the response block may be
>           very similar (identical) to the processed block, but
>           for the purposes of discussion may be treated as a new
>           block.
>
>      This is a good point.  It is analogous to a point I made in
>      Concept 4 in the Attachments section, which said that every
>      attachment should be referenced by a block or by some
>      attachment which is referenced by a block -- i.e., there is
>      no reason to continue carrying something that is not
>      referenceable. [unless we allow the specification to be
>      altered in a future node by adding a block that suddenly
>      referenced an attachment that formerly was not referenced --
>      this seems bizarre]   I would say the same about blocks that
>      were already fully processed.  Once there are no more
>      surviving references to them in the specification (i.e., all
>      relevant module applications have taken place), then they
>      can be dropped from the message.
>
>           Can an evaluation result in multiple response blocks ?
>
>      I would certainly advocate that.  This is the intention in a
>      specification such as seq { return M1(A), return M2(B) }.
>      You want the responses from both module applications to be
>      returned.
>
>
>        1. The specification of the module application should
>           indicate whether the response block is to be included
>           in a return message.
>        2. A module may be applied to more than one block (in a
>           single evaluation of the module).
>        3. The response block block generated by one module
>           application may also serve as an input for another
>           module application.  This permits the composition of
>           services.  For example, one module application might do
>           decompression, with its response block fed to a module
>           that did decryption, with its response block fed to an
>           application-specific module.
>        4. The ordering among module evaluations could be total or
>           partial, permitting parallelism if the processor is
>           capable of it.
>
>      Semantic Operations
>
>      The following grammar defines an abstract syntax for the
>      semantic operations of block evaluation that satisfies and
>      instantiates the above concepts.  It is emphasized that this
>      is an abstract syntax for the purpose of defining a notation
>      for discussing semantics and defining an abstract  module
>      processing model; the concrete syntax actually used in XML
>      Protocol messages may differ.
>
>        1. Module application -- a module is applied to one or
>           more blocks and can produce a resulting block
>           Composition of module applications -- a module is
>           applied to blocks produced by module applications
>
>           modname ::= < primitive modname syntax >
>           block   ::= < primitive block syntax >
>           modarg  ::= modapp | block
>           modapp  ::= modname "(" modarg ["," modarg]* ")"
>        2. Return values -- specifying a return value from a
>           module application
>
>
>
>
>           modexpr ::= return modapp | modapp
>        3. Sequential application -- the sequential execution of
>           expressions
>           Parallel application -- the parallel execution of
>           expressions
>
>           seqexpr ::= seq "{" expr ["," expr]* "}"
>           parexpr ::= par "{" expr ["," expr]* "}"
>           expr    ::= modexpr | seqexpr | parexpr
>
>      Examples of Abstract Module Operations
>
>      [These expressions could be viewed graphically, analogous to
>      the diagram showing handler processing in Figure 5.2.]
>

       1.   M1(A)                      application of  module M1 to block A
            return M1(A)               application, return value

       2.   M1(M2(A))                  composition
            return M1(M2(A))           composition, return composed value
            seq { M1(A), M2(A) }
            [MJH] Given my question
            about concept 4 above,
            should this just be
            another case of
            composition M2(M1(A))
            where M1(A) = A ?          sequence, 2 modules/same block
            [MAJ] No, M1(A) is not
            necessarily equal to A.

       3.   Since no return value was
            indicated, it presumably
            is being executed for      sequence, 1 module/different blocks
            side-effect on the world   sequence, 2 modules/different blocks
            somehow, and perhaps is in sequence, 2 modules/different
            the seq since it is        blocks/reverse order
            logically prior to the
            M2(A) execution.
            seq { M1(A), M1(B) }
            seq { M1(A), M2(B) }
            seq { M1(B), M2(A) }
       4.   par { M1(A), M1(B) }       parallel
            seq {M1(A), return M2(B) }
       5.                              return value from a module application
            seq {return M1(A), M2(B) } in a sequence
            par {M1(A), return M2(B) }
       6.                              return value from a module application
            par {return M1(A), M2(B) } in a parallel execution

       7.   seq {return M1(A), return  multiple return values from a sequence
            M2(B) }

       8.   par {return M1(A), return  multiple return values from a parallel
            M2(B) }                    execution
>
>
>
>      Issues
>
>        1. Should a module application be allowed to apply to zero
>           or more modargs?   Maybe the module application is
>           triggered purely for side-effect.
>           [MJH] If there are no blocks targetted for a given
>           modapp (Handler) how would the XMLP
>           application/processor know to invoke it ? This could be
>           a configuration setting in the application/processor I
>           suppose ?
>           [MAJ] The invocation order is determined by the
>           processing specification, not by the order of
>           appearance of blocks.  For example, seq {M1(A), M2(),
>           M3(B)}.  M2 gets invoked after M1(A), that's all.  It
>           is just 0-ary in terms of its arguments.
>        2. Should we allow an XML Protocol Message to contain zero
>           or more blocks?  The message could exist purely to
>           trigger module applications for their side-effects
>           without any message blocks. (This assumes that modules
>           can be applied to zero modargs.)
>           [MJH] If we provide a mechanism for triggering
>           non-targetted modargs then I see no reason why not.
>        3. Should a seq or par be allowed to contain zero or more
>           expressions?  They presumably would have no
>           computational effect, but would be harmless.
>        4. Should  return be implicit?  An alternative concept
>           would be to have every module application that is not
>           contained inside another module application return a
>           value (which may be void) for the reply.  Having an
>           explicit  return allows modules to produce a value, but
>           not always require that it be returned.  You can think
>           of return as a "module" that explicitly directs its
>           input (the output of a module application) into the
>           reply message.
>        5. Will we ever want to do something like this?  (not
>           allowed by current abstract syntax)
>           M1(return
>           M2(A))
>           composition, but only return value of M2(A)
>        6. How would implementations handle multiple parallel
>           returns without unbounded buffering since the return
>           wire format is serialized? (allowed by the current
>           abstract syntax -- should it be?)
>           par {return M1(A),(return M2(B)}            parallel,
>           multiple return values
>           [MJH] This could result in multiple return messages as
>           one solution.
>           [MAJ] Interesting suggestion.  Maybe this somehow
>           integrates with the message pattern that allows
>           asynchronous result reporting even from a single module
>           application (which I haven't described yet).
>

Received on Tuesday, 6 March 2001 17:59:56 UTC