Revs go missing in local sqlite DB


#1

Hello,

We’re using CB lite (1.4.1) in a c# windows service that stores data for a blog. The data is synced across a couple of web servers.

We have an issue where every few weeks random instances of docs lose all their revs in the local sqlite DB (i.e. the doc is in the DB but has no revs at all).

Deleting the local DB and re-syncing fixes the issue but we’d like to find out what the possible source of this could be.

We have one function that updates docs and I was wondering if it’s implemented incorrectly (see below). Any suggestions?

Thank you

EDIT:
A correction on my initial statement: The revs are not deleted, but they contain no data (i.e. json field is NULL) and the current field is ‘0’. So it seems that the ‘current’ rev is missing, not all of them.

private Document CreateOrUpdateDocumentWithJsonAttachments(string docId, Dictionary<string, object> properties, Dictionary<string, byte[]> attachments, bool existingOnly, DateTime? expireAt)
{
	if (properties == null && (attachments == null || attachments.Count == 0))
	{
		Debug.Assert(false);
		return null;
	}

	Document doc = (existingOnly) ? _Database.GetExistingDocument(docId) : _Database.GetDocument(docId);
	if (doc == null)
	{
		Debug.Assert(existingOnly);
		return null;
	}

	string docType = TypeForDocumentId(docId);
	Debug.Assert(docType != null);

	if (properties != null)
	{
		properties["type"] = docType;
		properties["syncUserId"] = "xyz";
	}

	SavedRevision sr = doc.Update((UnsavedRevision newRevision) =>
	{
		if (properties != null)
		{
			newRevision.SetProperties(properties);
		}

		if (attachments != null)
		{
			foreach (KeyValuePair<string, byte[]> pair in attachments)
			{
				if (pair.Value == null)
				{
					newRevision.RemoveAttachment(pair.Key);
				}
				else
				{
					newRevision.SetAttachment(pair.Key, "application/json", pair.Value);
				}
			}
		}
		else if (doc.CurrentRevision != null && doc.CurrentRevision.Attachments != null)
		{
			foreach (Attachment att in doc.CurrentRevision.Attachments)
			{
				newRevision.SetAttachment(att.Name, att.ContentType, att.Content);
			}
		}

#if DEBUG
		Debug.WriteLine(string.Format("Saved: {0}", doc.Id));
#endif

		return true;
	});

	if (expireAt.HasValue)
	{
		doc.ExpireAt(expireAt);
	}

	return doc;
}

#2

Well, there is a potential call to ExpireAt at the end of the block you shared. That means that at a certain point in the future the revisions will be purged from the local database, which seems to be exactly what you describe. Those are purges, so they are not replicated and if you delete and resync the database they will come back. Are you sure you want to be expiring the documents?


#3

Yes the expire date is always null. I’ll probably remove that anyway. The error occurs randomly, for different docs, on each of the servers that have a local sqlite DB. It’s a total mystery to me - I even tried to serialise access to the create/update function above and that didn’t help either. So for whatever reason the local sqlite DB gets out of sync and only a full re-sync fetches everything again.


#4

Removing it would be a more surefire way of guaranteeing that. Many times people tell me, or I tell others “it will never be X” and then it ends up being X in some corner case. If that’s not it though, then I will need a reproduction project to see what’s going on because it sounds like a bug. Revisions shouldn’t up and disappear for no reason.


#5

Ok it seems like you have edited your question. A “null” body means that the body has been compacted away and a current value of “0” means that there is a newer revision available. This sounds more normal than revisions being deleted.


#6

Yes that’s right I was wrong. Basically the current rev (i.e. current = 1) is missing and that causes the issue. I went through the code and made some changes, (e.g. added exception handling in the database change event) and I will upload again and see how it goes. We get this issue once every month or so - not easy to reproduce… but I will try.

Thank you!