incubator-couchdb-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jason Smith <...@iriscouch.com>
Subject Re: What's the best way to jack up the rev number?
Date Mon, 22 Aug 2011 09:03:28 GMT
On Mon, Aug 22, 2011 at 12:04 PM, Ryan Ramage <ryan.ramage@gmail.com> wrote:
> How to I grant mega points for a fantastic answer? Thanks Jason.
>
> A summary from the link....I have a master couchapp that clients pull
> replicate from. A refactoring of the couchapp may mess up the rev number for
> the main design doc. So i need a way to go past the rev number to force an
> update to the clients. Is there a better way?

Maybe a few ideas?

## The Bad Way: Sticking your fingers in _rev

It is a tempting illusion that _rev not only keeps a nice
AUTO_INCREMENT integer for every change, but it also contains an MD5
checksum of the entire document.

I think the _rev format has changed before, and it could change again.
I think also that BigCouch changes the _rev values.

## The Good Way: Work with _rev

I think your application has a concept of "upgrading" from one
revision to another. There is staging or development code, and there
is production code. Periodically you promote development code to
production. That sounds like two Git branches and it also sounds like
two doc ids. (Or two sets of doc ids.)

You can test and refactor your code all day long, in the temporary doc
(_design/dev). But in production (_design/pro), it's just like a long
Git history. Every revision built from the one previous, to the
beginning of time.

If you want to promote _design/dev, the latest deploy is
_rev=4-abcdef. So this will be the fifth revision deployed, right?
Hey! Stop reading the "_rev" field! But yeah, probably.

COPY /db/_design/dev
Destination: _design/pro?rev=4-abcdef

{"id":"_design/pro","rev":"5-12345whatever"}

Notice that each deployed _design/pro builds from the other, so it
will naturally float out to the slaves when they replicate.

In real-life, you may have add a middle step, pushing design documents
to production servers before actually publishing them. Once you push,
how long will it take couch to build new views? The answer is,
"Christ, who knows?"

Therefore you have to copy _design/dev to _design/staging and then
push that out into the wild. Then you have to query its views until
you are satisfied that they are fresh and fast. (You can compare
"update_seq" from /db vs. "update_seq" from /db/_design/ddoc/_info).
And only then do you HTTP copy from _design/staging to _design/pro and
let that propagate out.

## The Army Way: Create conflicts. Kill the weak.

You do not need a temporary "development" document. Just rebase all you want.

To deploy, note the good version's _rev and replicate to the central
server and you will have a conflict.

GET /db/_design/app?conflicts=true

{"_id":"_design/app", // ...
"_conflicts":["whatever", "old_revisions_here", "the_rev_i_like"]
}

You should spot the revision you like in there, so you can send out
DELETEs for all the rest (or batch them in _bulk_update).

Your tool might crash and forget the good _rev before replication
completes. I would say, just push again, but if you have a central
server, you can use a timestamp trick. The central maser is your
central time authority. Just `GET /` and check the "Date" header.

You can synchronize your client clock with this clock (it doesn't have
to be super accurate, within a few seconds--sometimes I time the query
and assume server time is the timestamp value plus half of the query
duration). You don't have to set the system clock, but you *do* have
to send and query timestamps which correspond with the server's
authority clock. (The server can sync with NTP, or it could even be
completely wrong, as long as we all agree it is the authority.)

When updating the design document, add an "updated_at" field.  This
value cannot be confirmed with validate_doc_update; so that is a
drawback.

If you've forgotten which revision is to be promoted (e.g. your
software crashed), you can fetch them all and take the latest
updated_at value.

-- 
Iris Couch

Mime
View raw message