[openstack-dev] [marconi] API design questions/concerns

Kurt Griffiths kurt.griffiths at rackspace.com
Tue Feb 19 17:25:42 UTC 2013


> It seems like the resources being changed are the messages...

That is correct. The client is applying a bulk PATCH operation to multiple messages. There's an implicit "claimed=false" query param that filters the messages to which the PATCH is applied.

> Isn't it more semantically correct to POST a claim request, and get a claim ID and list of messages back?

Not necessarily. json-patch [1] allows for adding to an existing resource:

    Because this operation is designed to add to existing objects and
    arrays, its target location will often not exist.

Also, from RFC 5789 [2]:

    With PATCH, however, the enclosed entity contains a set
    of instructions describing how a resource currently residing on the
    origin server should be modified to produce a new version.

That being said, the server is generating the ID for the claim object that is being added to each resource, and PATCH isn't really defined to apply to more than one resource. The implicit "claimed=false" filter is also a bit odd. I found this, again from RFC 5789:

    A comparison to POST is even more difficult, because POST is used in
    widely varying ways and can encompass PUT and PATCH-like operations
    if the server chooses.  If the operation does not modify the resource 
    identified by the Request-URI in a predictable way, POST should be
    considered instead of PATCH or PUT.

Given the not-so-predictable way PATCH is being used to claim messages in the current API draft, I'm inclined to agree that the approach to claiming messages should be changed.

As an alternative to using PATCH, the API could accept a POST to a "claims" collection, e.g.:

    POST /v1/12345/queues/foo-bar/claims

    { "ttl": 30 }

And the server would return the claim ID and a list of n messages associated with that claim, e.g.:

    {
      "claim": {
        "id": "a28ee94e-6cb4-11e2-b4d5-7703267a7926",
        "ttl": 30,
        "age": 0
      }

      "messages": [
        ...
      ]
    }

In this approach, a client could renew a claim by PATCHing its age to 0, or using PUT to overwrite the entire claim resource. A client could also DELETE a claim if it has been asked to shut down or has encountered a fatal error, to give a different client a chance to pick up the claimed messages. Furthermore, DELETEing a message could still take a claim_id parameter to ensure that a client can only remove a message that it has previously claimed.

One downside of this approach is that clients can't renew claims for individual messages; a renewal of a claim would renew it for the entire batch. So, if a client failed to process a single message but wanted to do the rest of the batch, it wouldn't have a way to release that one message for another worker to pick up. On the other hand, the client could simply DELETE its current claim and create a new one to get a fresh batch of messages to work on, effectively rebalancing the messages in the first claim across workers.

> We've had good luck building the v2 API for ceilometer using WSME.

Thanks for the tip; I'll check it out. However, Marconi is highly sensitive to latency, so WSME would have to be pretty darn fast for us to use it.

@kgriffs


[1]: http://tools.ietf.org/html/draft-ietf-appsawg-json-patch-10#section-4.1
[2]: http://tools.ietf.org/html/rfc5789#section-2.2





More information about the OpenStack-dev mailing list