[Pulp-list] Client Connection API Change

Nick Coghlan ncoghlan at redhat.com
Thu May 17 01:40:09 UTC 2012

On 05/16/2012 11:14 PM, Jay Dobies wrote:
> What does this mean for your code? Not much actually. For normal calls
> you still look at response.response_body to see the reply from the
> server. For async calls, instead of calling things like is_postponed or
> was_successful on the response object itself, you call it on the Task
> which is in the response_body. So response.is_running() becomes
> response.response_body.is_running(). I'm a lot happier about this since
> it's the task that's waiting, not the response itself, it's just a
> matter of making sure all of the existing calls have been migrated.

I'm wondering if it's worth streamlining this such that most client code
doesn't need to *care* if it got an immediate response or not. The model
that comes to mind is Twisted's Deferred objects and similar concepts in
the concurrent.futures module and other "Promise" style APIs.

The way that kind of approach would work is as follows:

-- response_body would always be a JSON document (even for calls that
returned a "queued" async result - in those cases, the response_body
would still contain the JSON task details reported by the async call)
-- a new "task" attribute would *always* be present, even for
synchronous calls. In the latter case, it would be an implementation of
the Task API that is preinitialised with all the info it needs rather
than having to query the server for status updates.

For guaranteed synchronous calls, you would access response_body
directly (and "task" would always be None).

For potentially asynchronous calls, client code would *always* go
through the new "task" attribute (which would never be None). If the
response happened to come back immediately, then the interface code
takes care of that by providing an appropriate dummy Task object.

Otherwise you're encouraging client code that has to do things like:

  if isinstance(response.response_body, Task):
     # Handle async case
     # Handle sync case

It's cleaner if code can do:

  Use response.response_body if you want the received JSON data
  Use response.task if you want the task status
  Use "response.task is None" to identify synchronous responses

This may mean you need a way to indicate in the JSON response itself
that the content is a reply to a potentially asynchronous request.


Nick Coghlan
Red Hat Hosted & Shared Services, Brisbane

More information about the Pulp-list mailing list