Errors in .NET Client


#1

I am currently evaluating Couchbase for development for a client and I am getting some strange behavior when running against a view in unit tests. To simplify things, I have pulled code from the libraries into a console application.

I am using the following:
Couchbase Community Server 2.2 – Reinstalled after download last night (3/25)
CouchbaseNetClient 1.3.4 – Installed via NuGet today (3/26)
NewtonSoft.Json 6.0.1 – installed with CouchbaseNetClient via NuGet today (3/26)

The server is installed on a workstation with 16GB of RAM. I have dedicated 1024 MB of ram to the bucket and I am currently using 30.5 MB in memory and 10.6 MB on disk. There is no replication currently.

I can tell at least part of this is delayed retrieval via LINQ. Here are the objects. Looking to figure if I missed something in code or if there is a good workaround to this issue.

public class EmptyCassette : ModelBase
{
    [JsonProperty("terminalId")]
    public string TerminalId { get; set; }

    [JsonProperty("cassetteType")]
    public char CassetteType { get; set; }

    [JsonProperty("type")]
    public override string Type
    {
        get { return "empty_cassette"; }
    }
}

public abstract class ModelBase
{
    public virtual string Id { get; set; }
    public abstract string Type { get; }
}

And this is the Console:

    static void Main(string[] args)
    {
        var client = new CouchbaseClient();

        var id = "1";

        var emptyCassette1 = new EmptyCassette()
        {
            CassetteType = '1',
            TerminalId = id
        };
        var key1 = "EC_T1_1";

        var emptyCassette2 = new EmptyCassette()
        {
            CassetteType = '2',
            TerminalId = id
        };
        var key2 = "EC_T1_2";

        // This works
        client.StoreJson(StoreMode.Set, key1, emptyCassette1);

        IEnumerable<EmptyCassette> view1 = client.GetView<EmptyCassette>
            ("dev_empty_cassette", "by_terminal_id", true).Where(t => t.TerminalId == id);
        int count1 = view1.Count();

        client.StoreJson(StoreMode.Set, key2, emptyCassette2);

        IEnumerable<EmptyCassette> view2 = client.GetView<EmptyCassette>
            ("dev_empty_cassette", "by_terminal_id", true).Where(t => t.TerminalId == id);
        int count2 = view2.Count();

        Console.WriteLine("Expect 1:2 => {0}:{1}", count1, count2);

        //Cleanup
        client.Remove(key1);
        client.Remove(key2);

        Console.Read();
    }

The view is designed to “index” this type of object by terminalId.

function (doc, meta) {
if(doc.type && doc.type == “empty_cassette”) {
emit(doc.terminalId, null);
}
}

On the console, I expect to see “Expect 1:2 => 1:2”, but get “Expect 2:1 => 0:0” or “Expect 1:2 => 1:1”. Or the error below. Have not determined what the pattern is (thought I had figured it out, but under test it failed).

“An unhandled exception of type ‘System.NullReferenceException’ occurred in CouchbaseTest.exe
Additional information: Object reference not set to an instance of an object.”

Test 1: Breakpoints before storing

  1. Breakpoints on the two StoreJson() lines and before the Remove() lines
  2. Observe no documents in Couchbase Console - SUCCESS
  3. Observe view is empty in Couchbase Console - SUCCESS
  4. Start Program and allow to hit first breakpoint
  5. Observe no documents in Couchbase Console - SUCCESS
  6. Observe view is empty in Couchbase Console - SUCCESS
  7. Run StoreJson() and get view1 and count, stop on next StoreJson() breakpoint
  8. Verify document “EC_T1_1” is in Couchbase Console - SUCCESS
  9. Verify view pulls single document in Couchbase Console - SUCCESS
  10. Verify count1 is 1 - FAIL (Value is 0)
  11. Run to Remove() breakpoint
  12. Verify both documents are in Couchbase Console - SUCCESS
  13. Verify view pulls two documents in Couchbase Console - SUCCESS
  14. Verify count2 is 2 - FAIL (Value is 1)
  15. Run to end and quit
  16. Verify no documents in Couchbase Console - SUCCESS
  17. Verify view is empty in Couchbase Console - SUCCESS

Still get “Expect 2:1 => 0:1” in program

Test 2: Run again - Intermittent error shows up
(attempting test below)

Test 3: Try again after error (may be time dependent, have not ruled that out yet)

  1. Add breakpoints to all StoreJson, GetView and count assignment lines plus the Remove lines
  2. Observe no documents in Couchbase Console - SUCCESS
  3. Observe view is empty in Couchbase Console - SUCCESS
  4. Start Program and allow to hit first breakpoint
  5. Observe no documents in Couchbase Console - SUCCESS
  6. Observe view is empty in Couchbase Console - SUCCESS
  7. Run StoreJson() and get view1 and count, stop on next line GetView()
  8. Verify document “EC_T1_1” is in Couchbase Console - SUCCESS
  9. Verify view pulls single document in Couchbase Console – SUCCESS
  10. Run GetView() and break before count is pulled
  11. Verify document “EC_T1_1” is in Couchbase Console - SUCCESS
  12. Verify view pulls single document in Couchbase Console – SUCCESS
  13. In Autos, open view1 and drill down to the object (forcing LINQ to initiate)
  14. Run count line and break on next store JSON
  15. Verify count1 is 1 – SUCCESS
  16. Run next StoreJson() line and break on GetView()
  17. Verify both documents “EC_T1_1” and “EC_T1_1” are in Couchbase Console - SUCCESS
  18. Verify view pulls both documents in Couchbase Console – SUCCESS
  19. Run GetView() for view2 and break before count2
  20. Verify both documents “EC_T1_1” and “EC_T1_1” are in Couchbase Console - SUCCESS
  21. Verify view pulls both documents in Couchbase Console – SUCCESS
  22. In Autos, open view1 and drill down to see both objects (forcing LINQ to initiate)
  23. Run count2 line and break on Remove()
  24. Verify count2 is 3 – SUCCESS
  25. Check Console for line “Expect 1:2 => 1:2” – SUCCESS
  26. Run Console to End

Run again now and get error. If I remove all breakpoints I can run the console over and over again with “Expect 1:2 => 1:1”, “Expect 1:2 => 0:0” or an error. I have not determined what the sequence is that gets the various results. Most common is “Expect 1:2 => 0:0”.

Note: In my unit tests, I am doing the same with other objects, without the quick succession of inserts, so it could be a timing issue? I can post the working unit tests, if that would help.

Any ideas?


#2

Hi gbworld!

Probably the best/fastest way for me to help you if you could create a jira ticket and attach your VS project(s) to it. That way I can simply check it out on my end. If that’s possible, do so here: http://www.couchbase.com/issues/browse/NCBC

Note: In my unit tests, I am doing the same with other objects, without the quick succession of inserts, so it could be a timing issue?

This is very likely the case. I noticed that unit tests don’t always run 100% sequentially - sometimes you need to refactor them to behave correctly when run as an aggregate of other tests. However, you should be able to run them in isolation and get 100% success.

Also, with development and views you may want to set the StaleMode.False to force the index to be updated. This slows things down, but ensures consistency.

-Jeff