incubator-couchdb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From J Chris Anderson <jch...@apache.org>
Subject Re: Proposal for changes in view server/protocol
Date Mon, 02 Aug 2010 19:52:41 GMT

On Aug 2, 2010, at 12:09 PM, Jason Smith wrote:

> On Tue, Aug 3, 2010 at 02:01, Mikeal Rogers <mikeal.rogers@gmail.com> wrote:
> 
>> Moving the js process and the *new* view server interaction protocol in to
>> erlang is what I meant by this.
>> 
> 
> That is getting far afield. If people want it in future CouchDB and it does
> not change web developer's Javascript or Python or language X view server,
> cool.
> 
> Anyway, I am excited about Chris's proposal. For some reason I just assumed
> anonymous callbacks weren't possible.
> 

To clear things up.

There are 2 discussions happing in this thread:

1) what is the ideal API and protocol for a more capable query server? (especially one that
can react differentially to doc update failures, can farm work out to multiple cores, etc)

2) how can we be backwards compatible with existing code and make it so you can respond to
an HTML form POST by rendering "whoops, someone else edited that before you did, please retry",
or "hey it looks like you failed the validation function for reason X"

They are both good discussions but it does us no good to blend them into one. This mail is
a discussion of 2 -- if you want to discuss 1) that is fine but I am not interested in it
because it is very long term at this time, and the key points are more along the lines of
"should we use emonk?" not "should we call it saveDoc() or attemptSave()?"

So, back to 2.

We can bolt onto the current implementation, something that allows for 2, without touching
any code other than the JavaScript query server. There may be other ways to do this from an
aesthetic standpoint, feel free to bikeshed those. But here is my proposal. Unless I'm mistaken
there is no other option that does not involve adding a new feature or breaking backwards
compatibility.

Currently the update function looks like this:

function(doc, req) {
        var field = req.query.field;
        var rev = req.query.rev;
        var value = req.query.value;
        var resp = "set "+field+" to "+value;
        doc[field] = value;
        doc._rev = rev; // use the query rev to preserve client MVCC. remove this line if
you prefer a free-for-all
        return [doc, resp];
      }

resp may also specify headers, like this:

resp = {
          "headers" : {
            "Content-Type" : "application/xml"
          },
          "body" : "<xml/>"
        }


My proposal is that we add the ability to return not just the response which should be sent
to the client on success, but also the response that should be sent on various failure conditions.

function(doc, req) {
   doc.updater_ran_at = new Date();
   var response_options = {};
    response_options.success = "you updated the document with a new timestamp. lucky you!";
    respond_options.conflict = "looks like someone else was updating the document at the same
time as you, and you lost the race condition. better luck next time.";
    respond_options.error = "the validation function says you aren't allowed to do that. I'm
not clever enough to guess why."
   return [doc, response_options];
}

You can see from this, that it would be possible to handle Jason's use case (even if it's
not satisfyingly elegant).

Also, the response_options.error could be enhanced to reflect a (partial) understanding of
validation errors (also no pretty, but it works).

function(doc, req) {
var oldDoc = JSON.parse(JSON.stringify(doc));
   doc.updater_ran_at = new Date();

var validation_fun, validation_error;
eval("validation_fun = "+this.validate_doc_update);

try {
validation_fun(doc, oldDoc, req.userCtx, req.secObj) //note secObj needs to be added to req
for lots of other reasons. 
} catch(e) {
validation_error = e;
}

   var response_options = {};
    response_options.success = "you updated the document with a new timestamp. lucky you!";
    respond_options.conflict = "looks like someone else was updating the document at the same
time as you, and you lost the race condition. better luck next time.";
    respond_options.error = "the validation function says you aren't allowed to do that. it
says: "+e.reason;
   return [doc, response_options];
}

All this can be implemented in a way that doesn't break backwards compat with existing update
function and existing alternate query server implementations.

Chris


Mime
View raw message