private void ChangeLogThenCrawlSync(IFolder remoteFolder, string remotePath, string localFolder)
{
// Once in a while, run a crawl sync, to make up for any server-side ChangeLog bug.
// The frequency of this is calculated based on the poll interval, so that:
// Interval=5 seconds -> every 6 hours -> about every 2160 iterations
// Interval=1 hours -> every 3 days -> about every 72 iterations
// Thus a good formula is: nb of iterations = 1 + 263907 / (pollInterval + 117)
double pollInterval = ConfigManager.CurrentConfig.GetFolder(repoInfo.Name).PollInterval;
if (changeLogIterationCounter > 263907 / (pollInterval/1000 + 117))
{
Logger.Debug("It has been a while since the last crawl sync, so launching a crawl sync now.");
CrawlSyncAndUpdateChangeLogToken(remoteFolder, remotePath, localFolder);
changeLogIterationCounter = 0;
return;
}
else
{
changeLogIterationCounter++;
}
// Calculate queryable number of changes.
Config.Feature features = null;
if (ConfigManager.CurrentConfig.GetFolder(repoInfo.Name) != null)
features = ConfigManager.CurrentConfig.GetFolder(repoInfo.Name).SupportedFeatures;
int maxNumItems = (features != null && features.MaxNumberOfContentChanges != null) ? // TODO if there are more items, either loop or force CrawlSync
(int)features.MaxNumberOfContentChanges : 50;
// Get last change token that had been saved on client side.
string lastTokenOnClient = database.GetChangeLogToken();
// Get last change log token on server side.
string lastTokenOnServer = CmisUtils.GetChangeLogToken(session);
if (lastTokenOnClient == lastTokenOnServer)
{
Logger.DebugFormat("No changes to sync, tokens on server and client are equal: \"{0}\"", lastTokenOnClient);
return;
}
if (lastTokenOnClient == null)
{
// Token is null, which means no sync has ever happened yet, so just sync everything from remote.
CrawlRemote(remoteFolder, remotePath, repoInfo.TargetDirectory, new List<string>(), new List<string>());
Logger.Info("Synced from remote, updating ChangeLog token: " + lastTokenOnServer);
database.SetChangeLogToken(lastTokenOnServer);
}
// ChangeLog tokens are different, so checking changes is needed.
var currentChangeToken = lastTokenOnClient;
IChangeEvents changes;
do
{
// Check which documents/folders have changed.
changes = session.GetContentChanges(currentChangeToken, IsPropertyChangesSupported, maxNumItems);
// First event was already processed previous.
var changeEvents = changes.ChangeEventList.Where(p => p != changes.ChangeEventList.FirstOrDefault()).ToList();
CrawlChangeLogSyncAndUpdateChangeLogToken(changeEvents, remoteFolder, remotePath, localFolder);
currentChangeToken = changes.LatestChangeLogToken;
database.SetChangeLogToken(currentChangeToken);
}
// Repeat if there were two many changes to fit in a single response.
while (changes.HasMoreItems ?? false);
database.SetChangeLogToken(lastTokenOnServer);
}