On Aug 2, 2010, at 12:09 PM, Jason Smith wrote:
> On Tue, Aug 3, 2010 at 02:01, Mikeal Rogers <[email protected]> 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