Return-Path: Delivered-To: apmail-couchdb-user-archive@www.apache.org Received: (qmail 61641 invoked from network); 9 Apr 2010 14:22:28 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 9 Apr 2010 14:22:28 -0000 Received: (qmail 65802 invoked by uid 500); 9 Apr 2010 14:22:27 -0000 Delivered-To: apmail-couchdb-user-archive@couchdb.apache.org Received: (qmail 65739 invoked by uid 500); 9 Apr 2010 14:22:26 -0000 Mailing-List: contact user-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: user@couchdb.apache.org Delivered-To: mailing list user@couchdb.apache.org Received: (qmail 65731 invoked by uid 99); 9 Apr 2010 14:22:26 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 09 Apr 2010 14:22:26 +0000 X-ASF-Spam-Status: No, hits=0.0 required=10.0 tests=FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_PASS,T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of jchris@gmail.com designates 209.85.160.52 as permitted sender) Received: from [209.85.160.52] (HELO mail-pw0-f52.google.com) (209.85.160.52) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 09 Apr 2010 14:22:19 +0000 Received: by pwi1 with SMTP id 1so2861905pwi.11 for ; Fri, 09 Apr 2010 07:21:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:content-type:mime-version :subject:from:in-reply-to:date:content-transfer-encoding:message-id :references:to:x-mailer; bh=U1izWYFzVOWG6i1SfgWplOXZvUWpxRYsHTKEqlRynSI=; b=IwZ2CYOPMsvABxXCEE7OiFgFGLMOsuvKJmzYNkhN7nRODxuj1nhB/Cv9hnXd4MQhf0 maUtgKa9nqBYLTq7gI8Y4wn78rSlH2fKvOVLVkKxgo85hAxt4R6CnXSuZjAN8HSbci68 NOtLE4dDHbnjgGVppwr7IuyvAI7V58f5KYvR0= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=content-type:mime-version:subject:from:in-reply-to:date :content-transfer-encoding:message-id:references:to:x-mailer; b=oYHoFDF60f3GL2Fc9eQG0tUwlkanrmiWpNeR35ILOkS/Dl5vzgp0Y7grPe+VidAqkk 0ZjpBkWKzDr65AOEwkkTaaNZZ185ho2wqyqRMNsuuFdcNl20U3RGa1F6DWtnkiWUyF+q kzXCr1hzRFPIA5gjp0qFn8/ZrcGux9/YCz09s= Received: by 10.141.101.17 with SMTP id d17mr207257rvm.30.1270822917224; Fri, 09 Apr 2010 07:21:57 -0700 (PDT) Received: from [192.168.1.101] (c-98-248-172-14.hsd1.ca.comcast.net [98.248.172.14]) by mx.google.com with ESMTPS id p1sm544190rvq.16.2010.04.09.07.21.53 (version=TLSv1/SSLv3 cipher=RC4-MD5); Fri, 09 Apr 2010 07:21:55 -0700 (PDT) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Apple Message framework v1077) Subject: Re: About denormalization and keep consistent From: J Chris Anderson In-Reply-To: Date: Fri, 9 Apr 2010 07:19:00 -0700 Content-Transfer-Encoding: quoted-printable Message-Id: <641CEC1C-ECF8-479C-8603-622D1FA8E8D3@gmail.com> References: To: user@couchdb.apache.org X-Mailer: Apple Mail (2.1077) X-Virus-Checked: Checked by ClamAV on apache.org On Apr 8, 2010, at 11:55 PM, faust 1111 wrote: > Yes i understand that listen _changes is better to get round race = conditions. >=20 > Cannot get your suggesting about > how i can track that all contents related to author was updated not 5 > of 50 but all. >=20 I think your question is valid. The answer is also simple. There is no = way to transactionally ensure that the author's name is updated = everywhere it appears. Your idea to do it in the app server, as the author changes their master = record, is troubling because it can lead to race conditions. The changes = method, where a name-update is an asynchronous process, is more robust, = because you can know for sure that *eventually* the author's name will = be changed everywhere it appears. It is probably best to make this clear through the UI with a message = like: "Your name has been changed in the master record. It could take a = few minutes for the change to appear throughout the site." In actuality, this is probably no different than in a relational = database (as in a relational database, you'd probably have a caching = layer that takes a few minutes to expire anyway.) > Thats ok. > I don't understand if listen feed _chenges, feed give me info only > about id & rev of changed doc, how i can get that author name is > changed? >=20 My method is to have a view of docs by author, and then query that view = for the old author's name, updating any docs that appear. This way if = new writes come in with the old name (due to there being out of date = replicas of the master record lingering, for instance) they will be = eventually updated as well. You could have a time-to-live of something = like 5 minutes (or longer if your system is giant) for the process which = is running the query for docs-that-say-Joe-but-should-say-Joseph and = updating them. _changes is just a convenient way to trigger that view query (so that = you aren't polling the view when nothing has happened in the database.) = With filtered changes, you can even be sure that you are only polling = the view when there will be something relevant to see. However, all this = _changes stuff is really just an optimization over brute force polling = the view once every N seconds, so you can add it later, when your app is = big enough that load starts to matter. Chris >=20 > 2010/4/9 Nicholas Orr : >> i don't think you are getting what the above people are suggesting... >>=20 >> Go read up on the _changes API :) >>=20 >> The basics are, every single change in the database is pushed into = this >> feed. All race conditions that are caused by your ruby way (via the = filter) >> are averted :) >>=20 >> Nick >>=20 >> On Fri, Apr 9, 2010 at 4:34 AM, faust 1111 = wrote: >>=20 >>> i means >>> when i do >>> Content.by_author(self).each {|content| >>> content.author_name =3D self.name; >>> content.save(bulk=3Dtrue) >>> } >>>=20 >>> i don't sure that all contents will updated may be only 5 and then >>> process crushed. >>>=20 >>> 2010/4/8 Andrew Melo : >>>> On Thu, Apr 8, 2010 at 12:53 PM, faust 1111 = wrote: >>>>> What difference? >>>>> if do >>>>> Author >>>>> after_save >>>>> if name_changed? >>>>> Content.by_author(self).each {|content| >>>>> content.author_name =3D self.name; >>>>> content.save(bulk=3Dtrue) >>>>> } >>>>>=20 >>>>> or i start backend process to track Author _changes. >>>>>=20 >>>>> This code not guarantee that all contents will updated. >>>>=20 >>>> I don't get your question. You asked how to make sure that you = could >>>> change a number of documents consistently, we suggested that you = watch >>>> _changes to catch any silly race conditions. Then, you told us you >>>> didn't need to use _changes, but you were worried that things would = be >>>> inconsistent. >>>>=20 >>>> Even with your code above, you get a race condition (if I = understand >>>> your ruby right, I don't know ruby much at all). Something could >>>> happen between when you check to see if a document needs to be = changed >>>> and the actual change occurs. Then, you're gonna get a conflict and >>>> have to write up the logic to handle that intelligently. >>>>=20 >>>> best, >>>> Andrew >>>>=20 >>>>=20 >>>>>=20 >>>>> 2010/4/8 Andrew Melo : >>>>>> On Thu, Apr 8, 2010 at 12:29 PM, faust 1111 >>> wrote: >>>>>>> I can catch changes in my app before save author, may be backend >>>>>>> process is surplus in my case. >>>>>>> i need consistent, when i update author name i must know that = all >>>>>>> contents with author was updated success. >>>>>>=20 >>>>>> Then their suggestion of watching _changes works for you. Start >>>>>> watching _changes. Make all your changes to the documents' = authors. >>>>>> Any changes that come through on _changes, make sure they have = the >>>>>> proper author. Keep watching _changes until you're sure that = nobody >>>>>> has stale data they're waiting submit. >>>>>>=20 >>>>>>=20 >>>>>>>=20 >>>>>>>=20 >>>>>>> 2010/4/8 Zachary Zolton : >>>>>>>> I suggest you check out the _changes API: >>>>>>>> http://books.couchdb.org/relax/reference/change-notifications >>>>>>>>=20 >>>>>>>> Basically, if you have doc types A & B, where B maintains a = denormed >>>>>>>> bit of A, then you can watch the _changes feed in a backend = process. >>>>>>>> When an A gets updated, hit a view of all B's related to that >>>>>>>> particular A, and update the dernomed data. >>>>>>>>=20 >>>>>>>> On Thu, Apr 8, 2010 at 10:20 AM, faust 1111 = >>> wrote: >>>>>>>>> Hi guy's >>>>>>>>> I return back to my problem with denormalization. >>>>>>>>>=20 >>>>>>>>> is it possible to keep consistent when apply denormalization? >>>>>>>>> For example >>>>>>>>> Content >>>>>>>>> have author (we store author name and id in Content) >>>>>>>>>=20 >>>>>>>>> When author name changed(that's happens not frequently) >>>>>>>>> i need find all content belong to this author and update = author name >>>>>>>>> but what if this operation not finished (not all docs was = updated) >>>>>>>>>=20 >>>>>>>>> What i can do in this case? >>>>>>>>> Thanks. >>>>>>>>>=20 >>>>>>>>=20 >>>>>>>=20 >>>>>>=20 >>>>>>=20 >>>>>>=20 >>>>>> -- >>>>>> -- >>>>>> Andrew Melo >>>>>>=20 >>>>>=20 >>>>=20 >>>>=20 >>>>=20 >>>> -- >>>> -- >>>> Andrew Melo >>>>=20 >>>=20 >>=20