/// <summary> /// Called by the CacheController when it wants this CacheRequest to be processed asynchronously. /// </summary> /// <param name="request">CacheRequest to be processed</param> /// <param name="state">User state object</param> /// <param name="cancellationToken"> </param> public async Task <CacheRequestResult> ProcessCacheRequestAsync(CacheRequest request, object state, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { cancellationToken.ThrowIfCancellationRequested(); } var wrapper = new AsyncArgsWrapper { UserPassedState = state, CacheRequest = request, Step = HttpState.Start }; wrapper = await ProcessRequest(wrapper, cancellationToken); CacheRequestResult cacheRequestResult; if (wrapper.CacheRequest.RequestType == CacheRequestType.UploadChanges) { cacheRequestResult = new CacheRequestResult( wrapper.CacheRequest.RequestId, wrapper.UploadResponse, wrapper.CacheRequest.Changes.Count, wrapper.Error, wrapper.Step, wrapper.UserPassedState); } else { cacheRequestResult = new CacheRequestResult( wrapper.CacheRequest.RequestId, wrapper.DownloadResponse, wrapper.Error, wrapper.Step, wrapper.UserPassedState); } return(cacheRequestResult); }
/// <summary> /// Called whenever the CacheRequestHandler proceeses an upload/download request. It is also responsible for /// issuing another request if it wasnt the last batch. In case of receiving an Upload response it calls the /// underlying provider with the status of the upload. In case of Download it notifies the local provider of the /// changes that it needs to save. /// </summary> private async Task <CacheRefreshStatistics> ProcessCacheRequestResults( CacheRefreshStatistics statistics, CacheRequestResult cacheRequestResult, CancellationToken cancellationToken) { try { if (cancellationToken.IsCancellationRequested) { cancellationToken.ThrowIfCancellationRequested(); } #region Error if (cacheRequestResult.Error != null) { // We have an error but we have a ChangeSetResponse with reading the upload respose // So we can serialize results and update dirty bits if (cacheRequestResult.ChangeSetResponse != null && cacheRequestResult.HttpStep == HttpState.End) { await this.localProvider.OnChangeSetUploaded(cacheRequestResult.Id, cacheRequestResult.ChangeSetResponse); } // Finally complete Refresh with error. statistics.Error = cacheRequestResult.Error; return(statistics); } #endregion #region Upload response if (cacheRequestResult.ChangeSetResponse != null) { if (cacheRequestResult.ChangeSetResponse.Error == null && cacheRequestResult.HttpStep == HttpState.End) { await this.localProvider.OnChangeSetUploaded(cacheRequestResult.Id, cacheRequestResult.ChangeSetResponse); } if (cacheRequestResult.ChangeSetResponse.Error != null) { statistics.Error = cacheRequestResult.ChangeSetResponse.Error; return(statistics); } // Increment the ChangeSets uploaded count statistics.TotalChangeSetsUploaded++; statistics.TotalUploads += cacheRequestResult.BatchUploadCount; // Update refresh stats foreach (var e1 in cacheRequestResult.ChangeSetResponse.ConflictsInternal) { if (e1 is SyncConflict) { statistics.TotalSyncConflicts++; } else { statistics.TotalSyncErrors++; } } return(statistics); } #endregion #region Download Response // it's a response to download Debug.Assert(cacheRequestResult.ChangeSet != null, "Completion is not for a download request."); // Increment the refresh stats if (cacheRequestResult.ChangeSet != null && cacheRequestResult.ChangeSet.Data != null && cacheRequestResult.ChangeSet.Data.Count > 0) { statistics.TotalChangeSetsDownloaded++; statistics.TotalDownloads += (uint)cacheRequestResult.ChangeSet.Data.Count; await this.localProvider.SaveChangeSet(cacheRequestResult.ChangeSet); } return(statistics); #endregion } catch (OperationCanceledException) { // Re throw the operation cancelled throw; } catch (Exception exp) { if (ExceptionUtility.IsFatal(exp)) { throw; } statistics.Error = exp; } return(statistics); }
/// <summary> /// Called whenever the CacheRequestHandler proceeses an upload/download request. It is also responsible for /// issuing another request if it wasnt the last batch. In case of receiving an Upload response it calls the /// underlying provider with the status of the upload. In case of Download it notifies the local provider of the /// changes that it needs to save. /// </summary> private async Task<CacheRefreshStatistics> ProcessCacheRequestResults(CacheRefreshStatistics statistics, CacheRequestResult cacheRequestResult, CancellationToken cancellationToken) { try { if (cancellationToken.IsCancellationRequested) cancellationToken.ThrowIfCancellationRequested(); #region Error if (cacheRequestResult.Error != null) { // Check to see if it was a UploadRequest in which case we will have to call OnChangeSetUploaded // with error to reset the dirty bits. if (cacheRequestResult.ChangeSetResponse != null) { // its an response to a upload await this.localProvider.OnChangeSetUploaded(cacheRequestResult.Id, cacheRequestResult.ChangeSetResponse); } // Finally complete Refresh with error. statistics.Error = cacheRequestResult.Error; return statistics; } #endregion #region Upload response if (cacheRequestResult.ChangeSetResponse != null) { // its an response to a upload await this.localProvider.OnChangeSetUploaded(cacheRequestResult.Id, cacheRequestResult.ChangeSetResponse); if (cacheRequestResult.ChangeSetResponse.Error != null) { statistics.Error = cacheRequestResult.ChangeSetResponse.Error; return statistics; } // Increment the ChangeSets uploaded count statistics.TotalChangeSetsUploaded++; statistics.TotalUploads += cacheRequestResult.BatchUploadCount; // Update refresh stats foreach (var e1 in cacheRequestResult.ChangeSetResponse.ConflictsInternal) { if (e1 is SyncConflict) { statistics.TotalSyncConflicts++; } else { statistics.TotalSyncErrors++; } } return statistics; } #endregion #region Download Response // it's a response to download Debug.Assert(cacheRequestResult.ChangeSet != null, "Completion is not for a download request."); // Increment the refresh stats if (cacheRequestResult.ChangeSet != null && cacheRequestResult.ChangeSet.Data != null && cacheRequestResult.ChangeSet.Data.Count > 0) { statistics.TotalChangeSetsDownloaded++; statistics.TotalDownloads += (uint)cacheRequestResult.ChangeSet.Data.Count; await this.localProvider.SaveChangeSet(cacheRequestResult.ChangeSet); } return statistics; #endregion } catch (OperationCanceledException) { // Re throw the operation cancelled throw; } catch (Exception exp) { if (ExceptionUtility.IsFatal(exp)) throw; statistics.Error = exp; } return statistics; }
/// <summary> /// Called by the CacheController when it wants this CacheRequest to be processed asynchronously. /// </summary> /// <param name="request">CacheRequest to be processed</param> /// <param name="state">User state object</param> /// <param name="cancellationToken"> </param> public async Task<CacheRequestResult> ProcessCacheRequestAsync(CacheRequest request, object state, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) cancellationToken.ThrowIfCancellationRequested(); var wrapper = new AsyncArgsWrapper { UserPassedState = state, CacheRequest = request, Step = HttpState.Start }; wrapper = await ProcessRequest(wrapper, cancellationToken); CacheRequestResult cacheRequestResult; if (wrapper.CacheRequest.RequestType == CacheRequestType.UploadChanges) { cacheRequestResult = new CacheRequestResult( wrapper.CacheRequest.RequestId, wrapper.UploadResponse, wrapper.CacheRequest.Changes.Count, wrapper.Error, wrapper.Step, wrapper.UserPassedState); } else { cacheRequestResult = new CacheRequestResult( wrapper.CacheRequest.RequestId, wrapper.DownloadResponse, wrapper.Error, wrapper.Step, wrapper.UserPassedState); } return cacheRequestResult; }
/// <summary> /// Called whenever the CacheRequestHandler proceeses an upload/download request. It is also responsible for /// issuing another request if it wasnt the last batch. In case of receiving an Upload response it calls the /// underlying provider with the status of the upload. In case of Download it notifies the local provider of the /// changes that it needs to save. /// </summary> private async Task <CacheRefreshStatistics> ProcessCacheRequestResults(CacheRefreshStatistics statistics, CacheRequestResult e, CancellationToken cancellationToken) { try { if (cancellationToken.IsCancellationRequested) { cancellationToken.ThrowIfCancellationRequested(); } if (e.Error != null) { // Check to see if it was a UploadRequest in which case we will have to call OnChangeSetUploaded // with error to reset the dirty bits. if (e.ChangeSetResponse != null) { // its an response to a upload this.localProvider.OnChangeSetUploaded(e.Id, e.ChangeSetResponse); } // Finally complete Refresh with error. statistics.Error = e.Error; } else if (e.ChangeSetResponse != null) { // its an response to a upload this.localProvider.OnChangeSetUploaded(e.Id, e.ChangeSetResponse); if (e.ChangeSetResponse.Error != null) { statistics.Error = e.ChangeSetResponse.Error; return(statistics); } // Increment the ChangeSets uploaded count statistics.TotalChangeSetsUploaded++; statistics.TotalUploads += e.BatchUploadCount; // Update refresh stats foreach (var e1 in e.ChangeSetResponse.ConflictsInternal) { if (e1 is SyncConflict) { statistics.TotalSyncConflicts++; } else { statistics.TotalSyncErrors++; } } // Dont enqueue another request if its been cancelled if (!cancellationToken.IsCancellationRequested) { if (!((bool)e.State)) { // Check to see if this was the last batch or else enqueue another pending Upload request statistics = await this.EnqueueUploadRequest(statistics, cancellationToken); } else { // That was the last batch. Issue an Download request statistics = await this.EnqueueDownloadRequest(statistics, cancellationToken); } } else { cancellationToken.ThrowIfCancellationRequested(); } } else // It means its an Download response { Debug.Assert(e.ChangeSet != null, "Completion is not for a download request."); // Increment the refresh stats if (e.ChangeSet != null) { statistics.TotalChangeSetsDownloaded++; statistics.TotalDownloads += (uint)e.ChangeSet.Data.Count; await this.localProvider.SaveChangeSet(e.ChangeSet); // Dont enqueue another request if its been cancelled if (!cancellationToken.IsCancellationRequested) { if (!e.ChangeSet.IsLastBatch) { // Enqueue the next download statistics = await this.EnqueueDownloadRequest(statistics, cancellationToken); } } else { cancellationToken.ThrowIfCancellationRequested(); } } } } catch (OperationCanceledException) { // Re throw the operation cancelled throw; } catch (Exception exp) { if (ExceptionUtility.IsFatal(exp)) { throw; } statistics.Error = exp; } return(statistics); }