[RCBC-166] Crash with eventmachine backend Created: 20/Mar/14  Updated: 20/Mar/14  Resolved: 20/Mar/14

Status: Resolved
Project: Couchbase Ruby client library
Component/s: None
Affects Version/s: 1.3.6
Fix Version/s: 1.3.7
Security Level: Public

Type: Bug Priority: Critical
Reporter: Sergey Avseyev Assignee: Sergey Avseyev
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment: ruby 2.0.0p353
eventmachine (1.0.3) 2ed44025e35518898c8589a610515e54a7b40c44
em-synchrony (1.0.3) ad17ce925fe49c45e1b5f713910e24d4798ae29c
couchbase (1.3.6)
  

Attachments: File Gemfile     File test.rb    

 Description   
ruby: ed.cpp:927: virtual void ConnectionDescriptor::Write(): Assertion `!bWatchOnly' failed.

#0 0x00007fd28b6bbc39 in __GI_raise (sig=sig@entry=0x6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1 0x00007fd28b6bd348 in __GI_abort () at abort.c:89
#2 0x00007fd28b6b4b96 in __assert_fail_base (fmt=0x7fd28b801d88 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x7fd28177eb26 "!bWatchOnly", file=file@entry=0x7fd28177e9a8 "ed.cpp", line=line@entry=0x3a7, function=function@entry=0x7fd28177edc0 <ConnectionDescriptor::Write()::__PRETTY_FUNCTION__> "virtual void ConnectionDescriptor::Write()") at assert.c:92
#3 0x00007fd28b6b4c42 in __GI___assert_fail (assertion=0x7fd28177eb26 "!bWatchOnly", file=0x7fd28177e9a8 "ed.cpp", line=0x3a7, function=0x7fd28177edc0 <ConnectionDescriptor::Write()::__PRETTY_FUNCTION__> "virtual void ConnectionDescriptor::Write()") at assert.c:101
#4 0x00007fd28177799d in ConnectionDescriptor::Write() () from /home/avsej/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/bundler/gems/eventmachine-2ed44025e355/lib/rubyeventmachine.so
#5 0x00007fd281764b18 in EventMachine_t::_RunEpollOnce() () from /home/avsej/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/bundler/gems/eventmachine-2ed44025e355/lib/rubyeventmachine.so
#6 0x00007fd28176489d in EventMachine_t::_RunOnce() () from /home/avsej/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/bundler/gems/eventmachine-2ed44025e355/lib/rubyeventmachine.so
#7 0x00007fd281764808 in EventMachine_t::Run() () from /home/avsej/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/bundler/gems/eventmachine-2ed44025e355/lib/rubyeventmachine.so
#8 0x00007fd281762262 in evma_run_machine () from /home/avsej/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/bundler/gems/eventmachine-2ed44025e355/lib/rubyeventmachine.so
#9 0x00007fd28175f42c in t_run_machine_without_threads(unsigned long) () from /home/avsej/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/bundler/gems/eventmachine-2ed44025e355/lib/rubyeventmachine.so
#10 0x00007fd28c9af4b2 in vm_call_cfunc_with_frame (th=th@entry=0x7fd28defb590, reg_cfp=reg_cfp@entry=0x7fd28c799ed0, ci=ci@entry=0x7fd28ef08980) at vm_insnhelper.c:1474
#11 0x00007fd28c9afa9e in vm_call_cfunc (ci=0x7fd28ef08980, reg_cfp=0x7fd28c799ed0, th=0x7fd28defb590) at vm_insnhelper.c:1564
#12 vm_call_method (th=0x7fd28defb590, cfp=0x7fd28c799ed0, ci=0x7fd28ef08980) at vm_insnhelper.c:1758
#13 0x00007fd28c9a9254 in vm_exec_core (th=th@entry=0x7fd28defb590, initial=initial@entry=0x0) at insns.def:1017
#14 0x00007fd28c99d43b in vm_exec (th=th@entry=0x7fd28defb590) at vm.c:1201
#15 0x00007fd28c99e704 in rb_iseq_eval_main (iseqval=iseqval@entry=0x7fd28ede6a08) at vm.c:1449
#16 0x00007fd28c849d2a in ruby_exec_internal (n=0x7fd28ede6a08) at eval.c:250
#17 0x00007fd28c84dc4d in ruby_exec_node (n=0x7fd28ede6a08) at eval.c:315
#18 ruby_run_node (n=<optimized out>) at eval.c:307


 Comments   
Comment by Sergey Avseyev [ 20/Mar/14 ]
http://review.couchbase.org/34738
Comment by Sergey Avseyev [ 20/Mar/14 ]
Thanks buger from community site for reporting the issue http://www.couchbase.com/communities/q-and-a/error-while-using-ruby-sdk-eventmachine




[RCBC-160] increment method increments negative value, contrary to method description Created: 15/Jan/14  Updated: 17/Jan/14  Resolved: 16/Jan/14

Status: Resolved
Project: Couchbase Ruby client library
Component/s: None
Affects Version/s: None
Fix Version/s: 1.3.5
Security Level: Public

Type: Task Priority: Major
Reporter: deepak vohra Assignee: Sergey Avseyev
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   
The method description of increment indicates:
"Couchbase Server stores numbers as unsigned numbers, therefore if you try to increment an existing negative number, it will cause an integer overflow and return a non-logical numeric result. "

But, if the increment makes the value a positive number the increment is applied and integer overflow does not occur. The integer overflow occurs only if after the increment the value is still negative.

Example does not generate error:
require 'rubygems'
require 'couchbase'
client = Couchbase.connect("http://localhost:8091")
client.set("2",-1)
client.increment("2",2)


Example generates error:
require 'rubygems'
require 'couchbase'
client = Couchbase.connect("http://localhost:8091")
client.set("2",-3)
client.increment("2",2)


 Comments   
Comment by Sergey Avseyev [ 16/Jan/14 ]
It is not a bug again. It just happened to look like working in some cases. Look at the patch here, where I have updated the ruby doc on this topic with the example.

http://review.couchbase.org/#/c/32543/1/ext/couchbase_ext/arithmetic.c

And yes, it should be a bug in the docs, but I didn't managed to find the same phrase in ruby docs. Could you give a link where you found it?
Comment by deepak vohra [ 16/Jan/14 ]
http://www.couchbase.com/docs/couchbase-sdk-ruby-1.0/couchbase-sdk-ruby-update-incr.html
Comment by Sergey Avseyev [ 16/Jan/14 ]
I recommend you to use the docs, generated from the library sources. The are located here http://www.couchbase.com/autodocs/

Also you can find docs from the rubygems site: http://rubygems.org/gems/couchbase
Comment by deepak vohra [ 16/Jan/14 ]
What is the difference between "# but it might look like working" and actually getting implemented?

The value output in subsequent get is accurate.

Or, is it the actual number being stored not being the number being retrieved with get?
Comment by Sergey Avseyev [ 17/Jan/14 ]
I mean, that what you are saying "generates error" is not an error at all. Just 64-bit integer wraps. Consider the following example

1.9.3p484 (main):001:0> require 'rubygems'
false
1.9.3p484 (main):002:0> require 'couchbase'
true
1.9.3p484 (main):003:0> client = Couchbase.connect("http://localhost:8091")
#<Couchbase::Bucket:0x000000014beeb0 "http://localhost:8091/pools/default/buckets/default/" transcoder=Couchbase::Transcoder::Document, default_flags=0x0, quiet=false, connected=true, timeout=2500000>
1.9.3p484 (main):004:0> client.set("2",-3)
11832122541421297664
1.9.3p484 (main):005:0> client.increment("2",2)
18446744073709551615
1.9.3p484 (main):006:0> client.get("2")
18446744073709551615
1.9.3p484 (main):007:0> client.increment("2",1)
0
1.9.3p484 (main):008:0> client.increment("2",1)
1

Do you see that it shows you "that garbage without any sense" just because you are incrementing not enough (in your first example, you have chosen the value bigger that absolute value of the number stored on the server"

The key point is that the server is storing the ascii representation of the number, this is why you can put negative number via set. But during increment it parse the number as signed 64bit integer and store into unsigned 64bit integer
Comment by deepak vohra [ 17/Jan/14 ]
Why does the PHP-equivalent method increment does not return the unsigned 64bit integer?

With the PHP Client library the following increment returns -4.

echo $cb->set("5", -5); //CAS value 10388951051056250880
   
echo $cb->increment("5", 1);//-4

But, the equivalent in Ruby returns the unsigned 64bit integer.

print client.set("5",-5) //CAS value 15131633266817368064
 print "\n<br>";
print client.increment("5",1) //18446744073709551612

Is the Ruby Client not applying the required conversion from the stored unsigned 64bit integer to the negative number?
 
Comment by Sergey Avseyev [ 17/Jan/14 ]
because php client returns you signed values and doesn't use uint64_t at all. ruby version gives you true unsigned value, as the server see it. There is no integer overflow in ruby actually. The numbers limited by the machine RAM only
Comment by deepak vohra [ 17/Jan/14 ]
Updated:
Is the Ruby Client not applying the required conversion from the stored unsigned 64bit integer to the signed value?

Should the statement about integer overflow be removed?
Comment by Sergey Avseyev [ 17/Jan/14 ]
the overflow still exists on the server. I just said that in ruby you can represent large numbers transparently

2.2.0p-1 (main):005:0> client.set("foo", -2)
8708394884148625408
2.2.0p-1 (main):006:0> client.incr("foo").class
Bignum
2.2.0p-1 (main):007:0> client.incr("foo").class
Fixnum

you see, it was expanded UINT64_MAX into Bignum, because it doesn't fit Fixnum on my computer, and then when I've incremented it twice it can fit Fixnum again.
Comment by deepak vohra [ 17/Jan/14 ]
The PHP client also stores the incremented value as unsigned 64bit integer and not the actual signed value, but returns the signed value.




[RCBC-161] :format set as :marshal generates Couchbase::Error::ValueFormat Created: 15/Jan/14  Updated: 16/Jan/14  Resolved: 16/Jan/14

Status: Resolved
Project: Couchbase Ruby client library
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: Public

Type: Task Priority: Major
Reporter: deepak vohra Assignee: Sergey Avseyev
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   
If the :format is set as :marshal in get method the Couchbase::Error::ValueFormat error is generated regradless of the type of value: numerical, string or JSON object.


   
client = Couchbase.connect("http://localhost:8091")
print client.set("catalog","journal")
print client.get("catalog",:format => :marshal)

#print client.set("3", 1)
#print client.get("3",:format => :marshal)

 Comments   
Comment by Sergey Avseyev [ 16/Jan/14 ]
This is not a bug

What behaviour do you expect?

When you don't specify format, it will use default transcoder class (you can find out using Couchbase::Bucket#transcoder method). In your example, it is easy to see what going on. Look at this IRB session

1.9.3p484 (main):001:0> require 'couchbase'
true
1.9.3p484 (main):002:0> client = Couchbase.connect
#<Couchbase::Bucket:0x00000001fd88a0 "http://localhost:8091/pools/default/buckets/default/" transcoder=Couchbase::Transcoder::Document, default_flags=0x0, quiet=false, connected=true, timeout=2500000>
1.9.3p484 (main):003:0> client.transcoder
Couchbase::Transcoder::Document
1.9.3p484 (main):004:0> client.set("catalog", "journal")
2508196931084222464
1.9.3p484 (main):005:0> client.get("catalog", :transcoder => nil)
"\"journal\""
1.9.3p484 (main):006:0> client.set("catalog", "journal", :format => :marshal)
6806784347694170112
1.9.3p484 (main):007:0> client.get("catalog", :transcoder => nil)
"\u0004\bI\"\fjournal\u0006:\u0006ET"
Comment by deepak vohra [ 16/Jan/14 ]
What is the :marshal format for? No example of :marshal is provided?
Comment by Sergey Avseyev [ 16/Jan/14 ]
:format option is legacy shortcut for specifying transcoder, which in charge of serializing values before putting them on wires and deserialise before passing back to user. in particular :marshal sets 'transcoder' attribute of connection to Couchbase::Transcoder::Marshal which is defined here https://github.com/couchbase/couchbase-ruby-client/blob/master/lib/couchbase/transcoder.rb#L74-L94

Using transcoders is more flexible but sometimes more verbose way to describe the value encoding. There only three formats supported: marshal (ruby's Marshal from stdlib), document (JSON) and plain (no transformations, but setting flags). In examples directory you can find user-defined transcoder, which performs compression (you can stack your transcoders) https://github.com/couchbase/couchbase-ruby-client/tree/master/examples/transcoders




[RCBC-93] Ruby Client does not handle the timeout appropriately Created: 24/Oct/12  Updated: 13/Jan/14  Resolved: 13/Jan/14

Status: Resolved
Project: Couchbase Ruby client library
Component/s: None
Affects Version/s: None
Fix Version/s: None
Security Level: Public

Type: Bug Priority: Major
Reporter: Anonymous Assignee: Sergey Avseyev
Resolution: Cannot Reproduce Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment: Ruby client 1.1.1

Attachments: File couch.rb    

 Description   
This is the problem that the customer is encountering
(Ruby code coming up):

Timeout::timeout(2) do
couch_client.get(key)
end

But we are seeing Couchbase::Error::Timeout exceptions being raised. I know the default timeout for the Couchbase client gem is greater than 2 seconds, so I'm wondering: what could cause Couchbase to return a timeout (0x16 error code) before it actually has time to timeout?

The complete ruby source code is attached , Please take a look at it.

------
support's analysis:
 The client is not timing out fast enough it should time out in 2.5 sec or something but instead it's waiting a long time.



 Comments   
Comment by Sergey Avseyev [ 13/Jan/14 ]
The issue was likely fixed in libcouchbase and currently is not reproducing




Generated at Thu Apr 17 13:24:31 CDT 2014 using JIRA 5.2.4#845-sha1:c9f4cc41abe72fb236945343a1f485c2c844dac9.