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
- Breakpoints on the two StoreJson() lines and before the Remove() lines
- Observe no documents in Couchbase Console - SUCCESS
- Observe view is empty in Couchbase Console - SUCCESS
- Start Program and allow to hit first breakpoint
- Observe no documents in Couchbase Console - SUCCESS
- Observe view is empty in Couchbase Console - SUCCESS
- Run StoreJson() and get view1 and count, stop on next StoreJson() breakpoint
- Verify document “EC_T1_1” is in Couchbase Console - SUCCESS
- Verify view pulls single document in Couchbase Console - SUCCESS
- Verify count1 is 1 - FAIL (Value is 0)
- Run to Remove() breakpoint
- Verify both documents are in Couchbase Console - SUCCESS
- Verify view pulls two documents in Couchbase Console - SUCCESS
- Verify count2 is 2 - FAIL (Value is 1)
- Run to end and quit
- Verify no documents in Couchbase Console - SUCCESS
- 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)
- Add breakpoints to all StoreJson, GetView and count assignment lines plus the Remove lines
- Observe no documents in Couchbase Console - SUCCESS
- Observe view is empty in Couchbase Console - SUCCESS
- Start Program and allow to hit first breakpoint
- Observe no documents in Couchbase Console - SUCCESS
- Observe view is empty in Couchbase Console - SUCCESS
- Run StoreJson() and get view1 and count, stop on next line GetView()
- Verify document “EC_T1_1” is in Couchbase Console - SUCCESS
- Verify view pulls single document in Couchbase Console – SUCCESS
- Run GetView() and break before count is pulled
- Verify document “EC_T1_1” is in Couchbase Console - SUCCESS
- Verify view pulls single document in Couchbase Console – SUCCESS
- In Autos, open view1 and drill down to the object (forcing LINQ to initiate)
- Run count line and break on next store JSON
- Verify count1 is 1 – SUCCESS
- Run next StoreJson() line and break on GetView()
- Verify both documents “EC_T1_1” and “EC_T1_1” are in Couchbase Console - SUCCESS
- Verify view pulls both documents in Couchbase Console – SUCCESS
- Run GetView() for view2 and break before count2
- Verify both documents “EC_T1_1” and “EC_T1_1” are in Couchbase Console - SUCCESS
- Verify view pulls both documents in Couchbase Console – SUCCESS
- In Autos, open view1 and drill down to see both objects (forcing LINQ to initiate)
- Run count2 line and break on Remove()
- Verify count2 is 3 – SUCCESS
- Check Console for line “Expect 1:2 => 1:2” – SUCCESS
- 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?