Return-Path: Delivered-To: apmail-couchdb-dev-archive@www.apache.org Received: (qmail 52437 invoked from network); 2 Aug 2010 21:43:38 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 2 Aug 2010 21:43:38 -0000 Received: (qmail 79172 invoked by uid 500); 2 Aug 2010 21:43:37 -0000 Delivered-To: apmail-couchdb-dev-archive@couchdb.apache.org Received: (qmail 79130 invoked by uid 500); 2 Aug 2010 21:43:37 -0000 Mailing-List: contact dev-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list dev@couchdb.apache.org Received: (qmail 79122 invoked by uid 99); 2 Aug 2010 21:43:37 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 02 Aug 2010 21:43:37 +0000 X-ASF-Spam-Status: No, hits=2.2 required=10.0 tests=FREEMAIL_FROM,HTML_MESSAGE,SPF_PASS,T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of mikeal.rogers@gmail.com designates 209.85.214.180 as permitted sender) Received: from [209.85.214.180] (HELO mail-iw0-f180.google.com) (209.85.214.180) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 02 Aug 2010 21:43:31 +0000 Received: by iwn8 with SMTP id 8so6045511iwn.11 for ; Mon, 02 Aug 2010 14:43:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:in-reply-to :references:date:message-id:subject:from:to:content-type; bh=VHoQryvZJwgEBVx3Ywed1toDFEbTBP9Q4DRo1lGidyI=; b=oCRJ6DZx/57PbNkjg9MlCThcQnoZ+owlu/AWaM50N6Rx8rmm/T5D9iACFYqdMuHZWS h8Kn98J9uK0zN76ZGKsCPtIbeXtdEusKCUZYsfJIQlxYaqK830Jfr+CrH4D4VRG/fIpO wvAgqnlxJCT04/lhFOZAfBJa66rWWSS25ciuw= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; b=Sd3UY4oqR6NL7HT3PV3cv72Nyeaq8oQ5ETtlmISEImllFhpB03TpSQRc2nbTizldLc XIQ65fQQ+fKezxe1vJVPZ0sm9naVE/hv7EeQVk6sirj/xeMkdww4tCZpeSps2sU8A6pq lHttyk2okRm7ngDjXu3O6DonCe2YCGyWr6saM= MIME-Version: 1.0 Received: by 10.231.184.16 with SMTP id ci16mr7784146ibb.23.1280785390487; Mon, 02 Aug 2010 14:43:10 -0700 (PDT) Received: by 10.231.186.202 with HTTP; Mon, 2 Aug 2010 14:43:10 -0700 (PDT) In-Reply-To: References: Date: Mon, 2 Aug 2010 14:43:10 -0700 Message-ID: Subject: Re: Proposal for changes in view server/protocol From: Mikeal Rogers To: dev@couchdb.apache.org Content-Type: multipart/alternative; boundary=0016367d6be23bdc8b048cde1606 --0016367d6be23bdc8b048cde1606 Content-Type: text/plain; charset=ISO-8859-1 On Mon, Aug 2, 2010 at 12:52 PM, J Chris Anderson wrote: > > On Aug 2, 2010, at 12:09 PM, Jason Smith wrote: > > > On Tue, Aug 3, 2010 at 02:01, Mikeal Rogers > 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" : "" > } > > > 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. > This isn't an API that I would want to use as a developer. It feels like a hack and only provides me a static way of dealing with success and error conditions. Evaling the validation function is even hackier and still doesn't handle the case where you get a rev conflict because someone updated the document while you were off in the update function. Also, I want to say that the proposal for an improved update function with the save() function could remain reverse compatible with the old one. You just detect when a save call was made when you take the update function return value and act accordingly. The bar shouldn't be set here that "no erlang work" should be undertaken to provide support for a fundamental use case nor should we shy away from improvements to the view server protocol so long as they are reverse compatible when the new features aren't used, which the save() proposal would satisfy. I agree that a complete rewrite of the protocol should be pushed off to another thread but surely we can discuss improvements to the existing protocol and alternate APIs. --0016367d6be23bdc8b048cde1606--