예제 #1
0
        private void SynchronizeInternalAsync(ISyncCallback callback, long syncSequenceId, int retry)
        {
            if (retry < 0)
            {
                var e = new SyncConflictingException();

                if (Logger.LoggingConfig.LogInnerMostError)
                {
                    _logger.Error(e, "Sync failed due to retry less than 0");
                }

                callback.OnError(this, new SyncConflictingException());
                return;
            }

            // pull from remote

            var lastSyncRevisions = _local.GetLastSyncRevision(IdentityId, Name);

            _remote.ListUpdatesAsync(IdentityId, Name, lastSyncRevisions,
                                     (listUpdatesErr, datasetUpdates) =>
            {
                if (syncSequenceId != _currentSyncSequenceId)
                {
                    var e = new SyncCanceledException();
                    callback.OnError(this, e);

                    if (Logger.LoggingConfig.LogInnerMostError)
                    {
                        _logger.Error(e, "INTERNAL LOG - Sync Failed due to inconsistent syncSequenceId.");
                    }

                    return;
                }

                if (listUpdatesErr != null)
                {
                    var e = new SyncNetworkException("Failed to pull from remote", listUpdatesErr);

                    if (Logger.LoggingConfig.LogInnerMostError)
                    {
                        _logger.Error(e, "INTERNAL LOG - Failed to pull from remote");
                    }

                    callback.OnError(this, e);
                    return;
                }

                if (!MergeRemoteRecords(callback, datasetUpdates))
                {
                    return;
                }

                // push to remote.
                // includes the records whose region is different.
                var localChanges = _local.GetDirtyRecords(IdentityId, Name);

                if (localChanges.Count == 0)
                {
                    callback.OnSuccess(this);
                    return;
                }

                _remote.PutRecordsAsync(IdentityId, Name,
                                        SdkUtils.ConvertSyncRevisionToString(datasetUpdates.SyncRevisions),
                                        datasetUpdates.SyncSessionToken, localChanges, (putErr, putResult) =>
                {
                    if (syncSequenceId != _currentSyncSequenceId)
                    {
                        var e = new SyncCanceledException();

                        if (Logger.LoggingConfig.LogInnerMostError)
                        {
                            _logger.Error(e, "INTERNAL LOG - Sync failed due to inconsistency of syncSequenceId");
                        }

                        callback.OnError(this, e);
                        return;
                    }

                    if (putErr != null)
                    {
                        if (Logger.LoggingConfig.LogInnerMostError)
                        {
                            _logger.Error(putErr, "INTERNAL LOG - Failed to push to remote: {0}", putErr.Message);
                        }

                        if (ErrorResponseException.IsDatasetConflict(putErr))
                        {
                            SynchronizeInternalAsync(callback, syncSequenceId, --retry);
                            return;
                        }

                        callback.OnError(this, new SyncNetworkException("Failed to push to remote", putErr));
                        return;
                    }

                    _local.ConditionallyPutRecords(IdentityId, Name, putResult.Records, localChanges);
                    _local.UpdateLastSyncRevision(IdentityId, Name, putResult.SyncRevisions);

                    callback.OnSuccess(this);
                });
            });
        }