Received: from exmf020-1.serverdata.net (10.240.130.9) by
 EXHUB020-2.exch020.serverdata.net (206.225.164.39) with Microsoft SMTP Server
 (TLS) id 8.3.264.0; Fri, 27 Jul 2012 23:49:43 -0700
Received: from localhost (localhost [127.0.0.1])	by exmf020-1.serverdata.net
 (Postfix) with ESMTP id 66D2759084;	Fri, 27 Jul 2012 23:49:43 -0700 (PDT)
X-Relayed-From: 209.85.220.173
X-Relayed-From-Added: Yes
X-Virus-Scanned: by amavisd-new at exmf020-1.serverdata.net
X-Spam-Flag: NO
X-Spam-Score: -1.001
X-Spam-Level:
X-Spam-Status: No, score=-1.001 tagged_above=-999 required=6
	tests=[BOTNET_SERVERWORDS=-0.2, RCVD_IN_DNSWL_LOW=-1,
	RCVD_IN_MSPIKE_H3=-0.3, SPF_PASS=-0.001, URI_IN_RU=0.5]
Received: from exmf020-1.serverdata.net ([127.0.0.1])	by localhost
 (exmf020-1.serverdata.net [127.0.0.1]) (amavisd-new, port 10024)	with ESMTP
 id 1C+Gq1zHBbjc; Fri, 27 Jul 2012 23:49:42 -0700 (PDT)
Received: from mail-vc0-f173.google.com (mail-vc0-f173.google.com
 [209.85.220.173])	(using TLSv1 with cipher RC4-SHA (128/128 bits))	(No client
 certificate requested)	by exmf020-1.serverdata.net (Postfix) with ESMTPS id
 8F42258FA3;	Fri, 27 Jul 2012 23:49:42 -0700 (PDT)
Received: by vcbfl15 with SMTP id fl15so3976660vcb.32        for <multiple
 recipients>; Fri, 27 Jul 2012 23:49:42 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=mime-version:in-reply-to:references:from:date:message-id:subject:to
         :cc:content-type;
        bh=jQeADm1XYn6t2Hu2XzRPn5xddhUO1n53pfrZEVU+0KQ=;
        b=tW+Sr78hWL9I2dwIgCR9Rb/yyGhkCi7aNmb8viVMB8pomJJGaLZXKshUdl1K/rDCIR
         aiJW0kOKin0UVjta67VBqsERFO0u06WVoYCrvXEXmlwiZGIIh3AL5RzZDukQI2FQvInF
         pAQxJ0X2vW0YPUrMoAifuJBd60kFQlWql1DZvSYMRv89TyLjX9zQ2DeaQAwyFApD4AYf
         5Qsk2l+1F508q88PmhsdFvj/AItSJV1IbnuqQv80Hsp5Y1E06BB4nL/xMKOGQi02FTTt
         O8thVFdopXjldY1HMFkZH03dJEboSxQZ7Z6xf27vefi5kbpX/hc/FUfwCs6zTue+q7mo
         5KAA==
Received: by 10.52.27.72 with SMTP id r8mr4325483vdg.14.1343458181909; Fri, 27
 Jul 2012 23:49:41 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.220.156.199 with HTTP; Fri, 27 Jul 2012 23:49:21 -0700 (PDT)
In-Reply-To: <CC386FE9.121F%karen.zeller@couchbase.com>
References: <CC386FE9.121F%karen.zeller@couchbase.com>
From: Sergey Avseyev <sergey.avseyev@gmail.com>
Date: Sat, 28 Jul 2012 09:49:21 +0300
Message-ID: <CAMB21XQF8KUeAu2x-FQ74d=6-epfOoj=h810uCCN+WfwXK1EyQ@mail.gmail.com>
Subject: Re: New Content for Review
To: Karen Zeller <karen.zeller@couchbase.com>
CC: Matt Ingenthron <matt@couchbase.com>, sdk_dev <sdk_dev@couchbase.com>
Return-Path: sergey.avseyev@gmail.com
Content-type: text/plain;
	charset="US-ASCII"
Content-transfer-encoding: 7bit

hi Karen.
second doc about advanced tricks:

* looks like it describes
handling temporary out of memory but title
of the section claims bulk set
and enumeration of the topics in
preface said bulk get. also as for me I do
t like this example because
it will retry for all errors not only server
memory errors

* "The callback received a result object, and we can check if
the
value was set with the success? method. If the value is nil, then
the
record has been successfully set; if it returns false, the
asynchronous
set had failed." nil is falsy value in ruby, so it should
be something like
"The callback received a result object, and we can
check if the value was
set with the success? method. If the value is
true, then the record has been
successfully set; otherwise you the
call considered failed and you should
check error property of the
result to get exception object.". Minor fix
here: to fix indentation:

Couchbase.bucket.run do |c|
  c.set("foo", "bar")
do |res1|
    # res1 is the Couchbase::Bucket::Result instance
    if
res1.success?
      c.get("foo") do |res2|
        puts res.value if
res2.success?
      end
    else
      puts "Something happened:
#{res1.error.message}"
    end
  end
end

* Two phase commit. It would be
nice to have links to complete source
code so that users could copy&paste it
and play a bit. Also I have
improved version with transfer() method
here
https://gist.github.com/3136027 Take a look at lines 47 and 54 of
the
script from link above, without them there is small chance of
unwanted
rewriting transaction document. And please  make
indentation
consistent there too, because you are splitting complete code
snippet
in a chunks (as a programmer I want cry bitter tears :) because
it
hard to follow the code). It might be ok, but you definitely should
post
links to complete sources, because PDF generator doesn't insert
spaces at
all. Try to copy and paste source chunks from PDF.

* Getting and Locking
I
think it worth to describe GETL operation here too, it is accessible
in
latest ruby as :lock parameter to
Bucket#get
http://rdoc.info/github/couchbase/couchbase-ruby-client/Couchbase
/Bucket#get-instance_method

* Using the Fastest Methods
I don't like the
example you are providing, Bucket#[] is just shortcut
to Bucket#get. So if
it will be example like below it will be much
better

keys = ["foo", "bar",
"baz"]
conn.get(keys)
conn.get(["foo", "bar", "baz"])
# and
even
conn.get("foo", "bar", "baz")

next example is invalid BTW, I'm talking
about
client.Increment("score", 100, 1);

1) there no method Increment, ruby
is case sensitive; 2) take a look
at examples in the
documentation
http://rdoc.info/github/couchbase/couchbase-ruby-client/Couchb
ase/Bucket#incr-instance_method
Proper version will
be:
client.increment("score", 1, :initial => 100)
#
or
client.increment("score", :delta => 1, :initial => 100)

Ohh, just
noticed that the example was from .net version. Tip: prefix
your examples in
little comment about what language are you using.

The users should be aware
about little increment feature
"1) retrieve it with a request to Couchbase,
2) add an amount to it,
if it exists, and 3) then store it back to the
database"
Should be:
2) add an amount to it, if it exists and store initial
value otherwise
It should be clear that the server won't create key and
increment it.
It only create OR increment it. Look at the
example:

conn.get("foo") #=> nil, key not found
conn.incr("foo", 1000,
:initial => 1)
conn.get("foo") #=> 1, because it didn't
exist
conn.incr("foo", 1000, :initial => 1)
conn.get("foo") #=>
1001

Append/Prepend: I like blog post of Dustin about implementing
Set
structure using
append
http://dustin.github.com/2011/02/17/memcached-set.html

* Maintaining
Persistent Connections with Couchbase
For ruby they will be persisted once
you will store them somewhere the
Garbage Collector cannot free it. I advice
to create the singleton
object which will be alive and store connection
reference there. There
is nice shortcut for this technique right in the
library. Users could
access the class-level method Couchbase.bucket instead
of
Couchbase.connect to get the instance. Couchbase.bucket will create
new
instance on first attempt and will store it in thread storage.
This means if
the  thread will be still alive by the time of the next
request to the ruby
process, the library won't create new instance.
Here is couple examples:

#
Simple example to connect using thread local
singleton
Couchbase.connectin_options = {
  :bucket => "my",
  :hostname =>
"example.com",
  :password => "secret"
}
# this call will user
connection_options to initialize
# new connection. By default
Couchbase.connection_options
# is empty
Couchbase.bucket.set("foo",
"bar")

# Amend the options of the singleton connection in
run-time
Couchbase.bucket.reconnect(:bucket => "another")

* Timeouts
Please
correct the units for ruby: microseconds. And it is generat
timeout for IO
operations here, but it could be changed to imitate
connection and data
timeouts. For example: "I want to wait no more 3
seconds when getting
connection but no more 1.5 seconds when
sending/receiving commands":

conn =
Couchbase.connect(:timeout => 3_000_000)
conn.timeout =
1_500_000
conn.set("foo", "bar")

The trick here that the timeout setting
applied to all next operation,
so setting it to 3 seconds first time
influence on connection
operation only.

**** general note, please pay
attention to code formatting, I guess
this document will be read by
programmers which would like to play
with things after reading, or just
dissect the code while reading,
clean formatting will help to concentrate
here. IMHO


Thanks for good work, this doc will be very valuable for
developers,
and having it online (in HTML) will help us to pointing asking
users.

On Saturday, July 28, 2012, Karen Zeller
<karen.zeller@couchbase.com> wrote:
> Hi,
> Attached are two documents for
review:
> -Persistent Connections in PHP. Let me know if this applies for
1.0 and 1.1, or just 1.1
> -Two-Phase Commits
> The respective commits
are:
>
> Persistent Connection in PHP:
https://github.com/karenzeller8/docs-1/commit/df74a5d8d8ff109adc89cf8ff6ad2e
0e9765f326
> Two Phase Commits (1.8, no Querying)
https://github.com/karenzeller8/docs-1/commit/99efc6cd1ddbc769ba7439bde188fd
9854afebc4
>
> Please send any additions, errors, or requested changes by
next Friday, August 3.
>
> Thanks,
> Karen


