Uploaded image for project: 'OASIS Open Data Protocol (OData) TC'
  1. OASIS Open Data Protocol (OData) TC
  2. ODATA-157

Specify how client correlates requests within a changeset with responses

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: V4.0_WD01
    • Fix Version/s: V4.0_WD01
    • Component/s: Protocol
    • Labels:
      None
    • Environment:

      [Proposed]

      Description

      The current $batch specification says that requests within a changeset need not be processed in the same order they are specified. For example, a service may re-order changes to reduce the likelihood of integrity violations by first doing deletes, then inserts, then updates. It goes on to say that the responses in a changeset must be 1:1 with the requests, but does not say they must be in the same order, and does not say how a client correlates a response within a changeset with a particular request within that changeset.

      Changesets do describe the use of a content-id header for allowing a statement within a batch to reference the results of a previous statement within the batch. For example, to add an order to a customer that was added within the same batch. However, it does not say that it is mandatory for the client to specify the content-id header for requests within a batch, nor does it say that it is mandatory for a service to return content-id headers supplied within the batch.

      It seems simplest to say that clients SHOULD specify a content-id header for requests within a changeset, and that service MUST return the content-id (if any) specified by the client. This allows the service to re-order changes within the changeset without having to buffer the response, and is arguably simpler for the client to correlate responses without having to rely on ordering.

        Attachments

          Activity

          mikep Michael Pizzo (Inactive) created issue -
          ralfhandl Ralf Handl made changes -
          Field Original Value New Value
          Fix Version/s WD01 [ 10247 ]
          Affects Version/s WD01 [ 10247 ]
          Hide
          ralfhandl Ralf Handl added a comment -

          Re-ordering responses only makes sense if the client actually specified a content-id in each request part. If we leave the choice to the client, we must limit the choice for the server.

          Adapted proposal accordingly.

          Show
          ralfhandl Ralf Handl added a comment - Re-ordering responses only makes sense if the client actually specified a content-id in each request part. If we leave the choice to the client, we must limit the choice for the server. Adapted proposal accordingly.
          ralfhandl Ralf Handl made changes -
          Proposal Specify that clients SHOULD specify a content-id header for requests within a changeset, and that services MUST return the specified content-id (if any) in the response. Clarify that not only can the service process requests within a changeset in any order, they can return results within the changeset in any order (but must still have a response for each request, or a single error for the changeset). Clients SHOULD specify a content-id header for each request within a changeset.
          Services MUST return the specified content-id (if any) in the response.
          Services MAY process requests within a changeset in any order.
          Services MAY return results within the changeset in any order if and only if the client specified a content-id for each request part.
          Services MUST return a response for each request, or a single error for the changeset.
          Hide
          ralfhandl Ralf Handl added a comment -

          What exactly do we gain with this content-id referencing and response reordering within changesets?

          We apparently still require correlation by ordering in the first-level batch request/response for the GET requests and the changesets themselves, so we introduce two ways of correlating request/response pairs.

          We apparently don't want to force clients to use content-id correlation, or else we would raise the entry barrier for clients.

          So we just introduce complexity for the servers, because they now MUST be able to cope with both ways.

          Show
          ralfhandl Ralf Handl added a comment - What exactly do we gain with this content-id referencing and response reordering within changesets? We apparently still require correlation by ordering in the first-level batch request/response for the GET requests and the changesets themselves, so we introduce two ways of correlating request/response pairs. We apparently don't want to force clients to use content-id correlation, or else we would raise the entry barrier for clients. So we just introduce complexity for the servers, because they now MUST be able to cope with both ways.
          Hide
          mikep Michael Pizzo (Inactive) added a comment -

          Changesets represent an atomic unit of change. The entire changeset may succeed or fail. At the end of applying the changeset the service must be in a consistent state that preserves integrity constraints (or the atomic request fails).

          Individual statements within a changeset may not preserve integrity. For example, there may be a statement to remove a link from an orderdetail to a product, and another statement to add a link from the same orderdetail to a different product. These statements may come in any order.

          The constraint that every orderdetail must have exactly one related product may be temporarily violated but the end result is consistent and preserves integrity of the set.

          In processing these requests, the service may reorder the individual requests in order to reduce the likelihood of an integrity constraint violation; for example, it may do all deletes first, followed by inserts, followed by updates. Allowing the service to return results in the order they are executed, rather than the order they are received, allows the service to stream results rather than buffer an entire changeset worth of results.

          Separate statements within a batch do not allow reordering by the service as they are each separate operations and must leave the database in a consistent state that does not violate constraints. Thus we can mandate that they are returned in order.

          Saying that services may return results in any order if and only if the client specifies a content-id means that the service needs to have all of the logic to buffer and reorder results in case the client doesn't specify content-id. Instead, we should simply say that the client must specify content-id if it cares about processing results; if it is simply going to generate the request, fire, and forget then it technically doesn't need the content-id, but if it cares about processing results it is not onerous to provide the content id.

          By the same token, I would also be fine saying that the client must specify a content-id on each request within a changeset, and that services must return this content-id, in order to keep things simple.

          Show
          mikep Michael Pizzo (Inactive) added a comment - Changesets represent an atomic unit of change. The entire changeset may succeed or fail. At the end of applying the changeset the service must be in a consistent state that preserves integrity constraints (or the atomic request fails). Individual statements within a changeset may not preserve integrity. For example, there may be a statement to remove a link from an orderdetail to a product, and another statement to add a link from the same orderdetail to a different product. These statements may come in any order. The constraint that every orderdetail must have exactly one related product may be temporarily violated but the end result is consistent and preserves integrity of the set. In processing these requests, the service may reorder the individual requests in order to reduce the likelihood of an integrity constraint violation; for example, it may do all deletes first, followed by inserts, followed by updates. Allowing the service to return results in the order they are executed, rather than the order they are received, allows the service to stream results rather than buffer an entire changeset worth of results. Separate statements within a batch do not allow reordering by the service as they are each separate operations and must leave the database in a consistent state that does not violate constraints. Thus we can mandate that they are returned in order. Saying that services may return results in any order if and only if the client specifies a content-id means that the service needs to have all of the logic to buffer and reorder results in case the client doesn't specify content-id. Instead, we should simply say that the client must specify content-id if it cares about processing results; if it is simply going to generate the request, fire, and forget then it technically doesn't need the content-id, but if it cares about processing results it is not onerous to provide the content id. By the same token, I would also be fine saying that the client must specify a content-id on each request within a changeset, and that services must return this content-id, in order to keep things simple.
          mikep Michael Pizzo (Inactive) made changes -
          Proposal Clients SHOULD specify a content-id header for each request within a changeset.
          Services MUST return the specified content-id (if any) in the response.
          Services MAY process requests within a changeset in any order.
          Services MAY return results within the changeset in any order if and only if the client specified a content-id for each request part.
          Services MUST return a response for each request, or a single error for the changeset.
          Clients SHOULD specify a content-id header for each request within a changeset.
          [MikePizzo: it might be simpler if we just always require the client to specify a content-id; it isn't hard to do and reduces the cases we have to define).
          Services MUST return the specified content-id (if any) in the response.
          Services MAY process requests within a changeset in any order.
          Services MAY return results within the changeset in any order if and only if the client specified a content-id for each request part.
          [MikePizzo: I would change the above rule to not depend on whether the client specifies a content-id for each request part]
          Services MUST return a response for each request, or a single error for the changeset.
          ralfhandl Ralf Handl made changes -
          Proposal Clients SHOULD specify a content-id header for each request within a changeset.
          [MikePizzo: it might be simpler if we just always require the client to specify a content-id; it isn't hard to do and reduces the cases we have to define).
          Services MUST return the specified content-id (if any) in the response.
          Services MAY process requests within a changeset in any order.
          Services MAY return results within the changeset in any order if and only if the client specified a content-id for each request part.
          [MikePizzo: I would change the above rule to not depend on whether the client specifies a content-id for each request part]
          Services MUST return a response for each request, or a single error for the changeset.
          Clients SHOULD specify a content-id header for each request within a changeset.
          [MikePizzo: it might be simpler if we just always require the client to specify a content-id; it isn't hard to do and reduces the cases we have to define).
          Services MUST return the specified content-id (if any) in the response.
          Services MAY process requests within a changeset in any order.
          Services MAY return results within the changeset in any order if and only if the client specified a content-id for each request part.
          [MikePizzo: I would change the above rule to not depend on whether the client specifies a content-id for each request part]
          [Ralf Handl: then the client MUST specify the content-id, otherwise it will not be able to interpret the response. And I really feel bad about making things harder for ALL clients just to make things easier for SOME services.]
          Services MUST return a response for each request, or a single error for the changeset.
          Hide
          ralfhandl Ralf Handl added a comment -

          A service may dispatch the GET requests in the top level of the batch request to several worker threads. Why impose on it to buffer all the query results just to return them in the request sequence? The server may stream back the responses from the fastest queries first.

          I find the streaming argument more convincing with GET requests, as per default PUT and DELETE requests return 204 No Content, which is easier to buffer than 100 sales orders with expanded items.

          And if clients (or the libraries they use) have to learn generating unique content-ids into request parts, then we can require that for all request types and give the servers complete freedom on how to assemble the response.

          Show
          ralfhandl Ralf Handl added a comment - A service may dispatch the GET requests in the top level of the batch request to several worker threads. Why impose on it to buffer all the query results just to return them in the request sequence? The server may stream back the responses from the fastest queries first. I find the streaming argument more convincing with GET requests, as per default PUT and DELETE requests return 204 No Content, which is easier to buffer than 100 sales orders with expanded items. And if clients (or the libraries they use) have to learn generating unique content-ids into request parts, then we can require that for all request types and give the servers complete freedom on how to assemble the response.
          Hide
          mikep Michael Pizzo (Inactive) added a comment -

          The GET scenario is better served by returning Accepted in the batch an allowing the client to fetch as they are available. For changesets, the results are required to be atomic so the changeset cannot return success or failure until all of the statements within it complete, so there is still value in allowing the service to reorder statements within a changeset.

          Show
          mikep Michael Pizzo (Inactive) added a comment - The GET scenario is better served by returning Accepted in the batch an allowing the client to fetch as they are available. For changesets, the results are required to be atomic so the changeset cannot return success or failure until all of the statements within it complete, so there is still value in allowing the service to reorder statements within a changeset.
          Hide
          ralfhandl Ralf Handl added a comment -

          I do not want to deny the service the right to reorder statements within a changeset.

          My concern is about the number of things a client has to learn in order to submit a batch request and understand its result.

          Previously these were three things:

          • wrap multiple requests into a batch request
          • unwrap a batch response into multiple responses
          • correlate individual requests and responses BY SEQUENCE

          The current proposal increases this to four things:

          • wrap multiple requests into a batch request
          • unwrap a batch response into multiple responses
          • correlate individual requests and responses on the first level BY SEQUENCE
          • correlate individual requests and responses on the second level (within changesets) BY CONTENT-ID

          My proposal is to get this back down to three things:

          • wrap multiple requests into a batch request
          • unwrap a batch response into multiple responses
          • correlate individual requests and responses BY CONTENT-ID
          Show
          ralfhandl Ralf Handl added a comment - I do not want to deny the service the right to reorder statements within a changeset. My concern is about the number of things a client has to learn in order to submit a batch request and understand its result. Previously these were three things: wrap multiple requests into a batch request unwrap a batch response into multiple responses correlate individual requests and responses BY SEQUENCE The current proposal increases this to four things: wrap multiple requests into a batch request unwrap a batch response into multiple responses correlate individual requests and responses on the first level BY SEQUENCE correlate individual requests and responses on the second level (within changesets) BY CONTENT-ID My proposal is to get this back down to three things: wrap multiple requests into a batch request unwrap a batch response into multiple responses correlate individual requests and responses BY CONTENT-ID
          Hide
          mikep Michael Pizzo (Inactive) added a comment -

          Agreed that the client should always specify Content-ID within the changeset and should rely on the returned Content-ID to correlate responses. We should not add the additional burden on the client or server to correlate requests within a changeset by sequence. This allows the server to re-order related items within a changeset in order to execute the set of items that make up a single transaction, and still stream results.

          The server has no transactional need to re-order the items within the batch; each separate item within a batch is done as a separate atomic transaction. If these are executed asynchronously they should return 202 Accepted, rather than rely on the server to serialize if and how the individual requests are completed, blocking until a next result is available or returning a partial batch.

          Show
          mikep Michael Pizzo (Inactive) added a comment - Agreed that the client should always specify Content-ID within the changeset and should rely on the returned Content-ID to correlate responses. We should not add the additional burden on the client or server to correlate requests within a changeset by sequence. This allows the server to re-order related items within a changeset in order to execute the set of items that make up a single transaction, and still stream results. The server has no transactional need to re-order the items within the batch; each separate item within a batch is done as a separate atomic transaction. If these are executed asynchronously they should return 202 Accepted, rather than rely on the server to serialize if and how the individual requests are completed, blocking until a next result is available or returning a partial batch.
          mikep Michael Pizzo (Inactive) made changes -
          Proposal Clients SHOULD specify a content-id header for each request within a changeset.
          [MikePizzo: it might be simpler if we just always require the client to specify a content-id; it isn't hard to do and reduces the cases we have to define).
          Services MUST return the specified content-id (if any) in the response.
          Services MAY process requests within a changeset in any order.
          Services MAY return results within the changeset in any order if and only if the client specified a content-id for each request part.
          [MikePizzo: I would change the above rule to not depend on whether the client specifies a content-id for each request part]
          [Ralf Handl: then the client MUST specify the content-id, otherwise it will not be able to interpret the response. And I really feel bad about making things harder for ALL clients just to make things easier for SOME services.]
          Services MUST return a response for each request, or a single error for the changeset.
          Clients SHOULD specify a content-id header for each request within a changeset.
          [MikePizzo: it might be simpler if we just always require the client to specify a content-id; it isn't hard to do and reduces the cases we have to define).
          Services MUST return the specified content-id (if any) in the response.
          Services MAY process requests within a changeset in any order.
          Services MAY return results within the changeset in any order if and only if the client specified a content-id for each request part.
          [MikePizzo: I would change the above rule to not depend on whether the client specifies a content-id for each request part]
          [Ralf Handl: then the client MUST specify the content-id, otherwise it will not be able to interpret the response. And I really feel bad about making things harder for ALL clients just to make things easier for SOME services.]
          [MikePizzo: agree that it is simpler if the client always specifies content-id and correlates requests w/in a changeset to responses according to that content-id; we should not require services to have dual logic depending on whether or not content-ids are provided. I actually think correlating requests within a changeset by id is straightforward to for the client, since the changeset is atomic and all values will be returned prior to processing the next statement in the batch.]
          Services MUST return a response for each request, or a single error for the changeset.
          Hide
          ralfhandl Ralf Handl added a comment -

          Let's start from where we agree and go one little step further:

          The client should always specify Content-ID and should rely on the returned Content-ID to correlate responses.

          No assumptions about ordering in the response.

          Show
          ralfhandl Ralf Handl added a comment - Let's start from where we agree and go one little step further: The client should always specify Content-ID and should rely on the returned Content-ID to correlate responses. No assumptions about ordering in the response.
          Hide
          ralfhandl Ralf Handl added a comment -

          Old Proposal:

          Clients SHOULD specify a content-id header for each request within a changeset.
          [MikePizzo: it might be simpler if we just always require the client to specify a content-id; it isn't hard to do and reduces the cases we have to define).
          Services MUST return the specified content-id (if any) in the response.
          Services MAY process requests within a changeset in any order.
          Services MAY return results within the changeset in any order if and only if the client specified a content-id for each request part.
          [MikePizzo: I would change the above rule to not depend on whether the client specifies a content-id for each request part]
          [Ralf Handl: then the client MUST specify the content-id, otherwise it will not be able to interpret the response. And I really feel bad about making things harder for ALL clients just to make things easier for SOME services.]
          [MikePizzo: agree that it is simpler if the client always specifies content-id and correlates requests w/in a changeset to responses according to that content-id; we should not require services to have dual logic depending on whether or not content-ids are provided. I actually think correlating requests within a changeset by id is straightforward to for the client, since the changeset is atomic and all values will be returned prior to processing the next statement in the batch.]
          Services MUST return a response for each request, or a single error for the changeset.

          Show
          ralfhandl Ralf Handl added a comment - Old Proposal: Clients SHOULD specify a content-id header for each request within a changeset. [MikePizzo: it might be simpler if we just always require the client to specify a content-id; it isn't hard to do and reduces the cases we have to define). Services MUST return the specified content-id (if any) in the response. Services MAY process requests within a changeset in any order. Services MAY return results within the changeset in any order if and only if the client specified a content-id for each request part. [MikePizzo: I would change the above rule to not depend on whether the client specifies a content-id for each request part] [Ralf Handl: then the client MUST specify the content-id, otherwise it will not be able to interpret the response. And I really feel bad about making things harder for ALL clients just to make things easier for SOME services.] [MikePizzo: agree that it is simpler if the client always specifies content-id and correlates requests w/in a changeset to responses according to that content-id; we should not require services to have dual logic depending on whether or not content-ids are provided. I actually think correlating requests within a changeset by id is straightforward to for the client, since the changeset is atomic and all values will be returned prior to processing the next statement in the batch.] Services MUST return a response for each request, or a single error for the changeset.
          ralfhandl Ralf Handl made changes -
          Proposal Clients SHOULD specify a content-id header for each request within a changeset.
          [MikePizzo: it might be simpler if we just always require the client to specify a content-id; it isn't hard to do and reduces the cases we have to define).
          Services MUST return the specified content-id (if any) in the response.
          Services MAY process requests within a changeset in any order.
          Services MAY return results within the changeset in any order if and only if the client specified a content-id for each request part.
          [MikePizzo: I would change the above rule to not depend on whether the client specifies a content-id for each request part]
          [Ralf Handl: then the client MUST specify the content-id, otherwise it will not be able to interpret the response. And I really feel bad about making things harder for ALL clients just to make things easier for SOME services.]
          [MikePizzo: agree that it is simpler if the client always specifies content-id and correlates requests w/in a changeset to responses according to that content-id; we should not require services to have dual logic depending on whether or not content-ids are provided. I actually think correlating requests within a changeset by id is straightforward to for the client, since the changeset is atomic and all values will be returned prior to processing the next statement in the batch.]
          Services MUST return a response for each request, or a single error for the changeset.
          Clients MUST specify a content-id header for each request within a changeset.
          Servers MAY return responses within a changeset in any order.
          Servers MUST include the content-id header in each response, so clients can correlate requests and responses.

          Accepted: https://www.oasis-open.org/apps/org/workgroup/odata/download.php/47764/latest/odata-meeting-19_on-20121220-minutes.html
          Status New [ 10000 ] Open [ 1 ]
          ralfhandl Ralf Handl made changes -
          Resolution Fixed [ 1 ]
          Status Open [ 1 ] Resolved [ 5 ]
          ralfhandl Ralf Handl made changes -
          Assignee Michael Pizzo [ mikep ]
          ralfhandl Ralf Handl made changes -
          Assignee Ralf Handl [ ralfhandl ]
          ralfhandl Ralf Handl made changes -
          handl Ralf Handl made changes -
          Assignee Ralf Handl [ ralfhandl ] Ralf Handl [ handl ]

            People

            • Assignee:
              handl Ralf Handl
              Reporter:
              mikep Michael Pizzo (Inactive)
            • Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: