sdk/dotnet/src/Microsoft.Datasync.Client/Offline/SyncContext.cs
/// <summary>
/// Executes a single operation within the queue.
/// </summary>
/// <param name="operation">The operation to execute.</param>
/// <param name="batch">The operation batch being executed.</param>
/// <param name="removeFromQueueOnSuccess">If <c>true</c>, remove the operation from the queue when successful.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe.</param>
/// <returns>A task that returns <c>true</c> if the execution was successful when complete.</returns>
Executes a single operation within the queue.
Executes a single operation within the queue .
protected virtual async Task<bool> ExecutePushOperationAsync(TableOperation operation, OperationBatch batch, bool removeFromQueueOnSuccess, CancellationToken cancellationToken)
        {
            if (operation.IsCancelled || cancellationToken.IsCancellationRequested)
            {
                return false;
            }
            if (operation.Item == null)
            {
                try
                {
                    operation.Item = await OfflineStore.GetItemAsync(operation.TableName, operation.ItemId, cancellationToken).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    batch.Abort(PushStatus.CancelledByOfflineStoreError);
                    throw new OfflineStoreException($"Failed to read Item '{operation.ItemId}' from table '{operation.TableName}' in the offline store.", ex);
                }
                if (operation.Item == null)
                {
                    var item = new JObject(new JProperty(SystemProperties.JsonIdProperty, operation.ItemId));
                    await batch.AddErrorAsync(operation, null, null, item, cancellationToken).ConfigureAwait(false);
                    return false;
                }
            }
            await OperationsQueue.TryUpdateOperationStateAsync(operation, TableOperationState.Attempted, batch, cancellationToken).ConfigureAwait(false);
            operation.Item = ServiceSerializer.RemoveSystemProperties(operation.Item, out string version);
            if (version != null)
            {
                operation.Item[SystemProperties.JsonVersionProperty] = version;
            }
            JObject result = null;
            Exception error = null;
            try
            {
                result = await operation.ExecuteOperationOnRemoteServiceAsync(ServiceClient, cancellationToken).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                await OperationsQueue.TryUpdateOperationStateAsync(operation, TableOperationState.Failed, batch, cancellationToken).ConfigureAwait(false);
                if (ex is HttpRequestException || ex is TimeoutException)
                {
                    batch.Abort(PushStatus.CancelledByNetworkError);
                    return false;
                }
                else if (ex is DatasyncInvalidOperationException ios && ios.Response?.StatusCode == HttpStatusCode.Unauthorized)
                {
                    batch.Abort(PushStatus.CancelledByAuthenticationError);
                    return false;
                }
                else if (ex is PushAbortedException)
                {
                    batch.Abort(PushStatus.CancelledByOperation);
                    return false;
                }
                error = ex;
            }
            if (error == null && operation.CanWriteResultToStore && result?.Value<string>(SystemProperties.JsonIdProperty) != null)
            {
                try
                {
                    await OfflineStore.UpsertAsync(operation.TableName, new[] { result }, true, cancellationToken).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    batch.Abort(PushStatus.CancelledByOfflineStoreError);
                    throw new OfflineStoreException($"Failed to update item '{operation.ItemId}' in table '{operation.TableName}' of the offline store.", ex);
                }
            }
            else if (error != null)
            {
                string rawResult = null;
                if (error is DatasyncInvalidOperationException iox && iox.Response != null)
                {
                    HttpStatusCode? statusCode = iox.Response.StatusCode;
                    try
                    {
                        rawResult = await iox.Response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
                        result = ServiceClient.Serializer.DeserializeObjectOrDefault(rawResult);
                    }
                    catch {  }
                    await batch.AddErrorAsync(operation, statusCode, rawResult, result, cancellationToken).ConfigureAwait(false);
                }
            }
            if (removeFromQueueOnSuccess && error == null)
            {
                await OperationsQueue.DeleteOperationByIdAsync(operation.Id, operation.Version, cancellationToken).ConfigureAwait(false);
            }
            return error == null;
        }
protected virtual async Task < bool > ExecutePushOperationAsync ( TableOperation operation , OperationBatch batch , bool removeFromQueueOnSuccess , CancellationToken cancellationToken ) { if ( operation . IsCancelled || cancellationToken . IsCancellationRequested ) { return false ; } if ( operation . Item == null ) { try { operation . Item = await OfflineStore . GetItemAsync ( operation . TableName , operation . ItemId , cancellationToken ) . ConfigureAwait ( false ) ; } catch ( Exception ex ) { batch . Abort ( PushStatus . CancelledByOfflineStoreError ) ; throw new OfflineStoreException ( $" Failed to read Item ' { operation . ItemId } ' from table ' { operation . TableName } ' in the offline store. " , ex ) ; } if ( operation . Item == null ) { var item = new JObject ( new JProperty ( SystemProperties . JsonIdProperty , operation . ItemId ) ) ; await batch . AddErrorAsync ( operation , null , null , item , cancellationToken ) . ConfigureAwait ( false ) ; return false ; } } await OperationsQueue . TryUpdateOperationStateAsync ( operation , TableOperationState . Attempted , batch , cancellationToken ) . ConfigureAwait ( false ) ; operation . Item = ServiceSerializer . RemoveSystemProperties ( operation . Item , out string version ) ; if ( version != null ) { operation . Item [ SystemProperties . JsonVersionProperty ] = version ; } JObject result = null ; Exception error = null ; try { result = await operation . ExecuteOperationOnRemoteServiceAsync ( ServiceClient , cancellationToken ) . ConfigureAwait ( false ) ; } catch ( Exception ex ) { await OperationsQueue . TryUpdateOperationStateAsync ( operation , TableOperationState . Failed , batch , cancellationToken ) . ConfigureAwait ( false ) ; if ( ex is HttpRequestException || ex is TimeoutException ) { batch . Abort ( PushStatus . CancelledByNetworkError ) ; return false ; } else if ( ex is DatasyncInvalidOperationException ios && ios . Response ? . StatusCode == HttpStatusCode . Unauthorized ) { batch . Abort ( PushStatus . CancelledByAuthenticationError ) ; return false ; } else if ( ex is PushAbortedException ) { batch . Abort ( PushStatus . CancelledByOperation ) ; return false ; } error = ex ; } if ( error == null && operation . CanWriteResultToStore && result ? . Value < string > ( SystemProperties . JsonIdProperty ) != null ) { try { await OfflineStore . UpsertAsync ( operation . TableName , new [ ] { result } , true , cancellationToken ) . ConfigureAwait ( false ) ; } catch ( Exception ex ) { batch . Abort ( PushStatus . CancelledByOfflineStoreError ) ; throw new OfflineStoreException ( $" Failed to update item ' { operation . ItemId } ' in table ' { operation . TableName } ' of the offline store. " , ex ) ; } } else if ( error != null ) { string rawResult = null ; if ( error is DatasyncInvalidOperationException iox && iox . Response != null ) { HttpStatusCode ? statusCode = iox . Response . StatusCode ; try { rawResult = await iox . Response . Content . ReadAsStringAsync ( cancellationToken ) . ConfigureAwait ( false ) ; result = ServiceClient . Serializer . DeserializeObjectOrDefault ( rawResult ) ; } catch { } await batch . AddErrorAsync ( operation , statusCode , rawResult , result , cancellationToken ) . ConfigureAwait ( false ) ; } } if ( removeFromQueueOnSuccess && error == null ) { await OperationsQueue . DeleteOperationByIdAsync ( operation . Id , operation . Version , cancellationToken ) . ConfigureAwait ( false ) ; } return error == null ; }
Executes a single operation within the queue.
Executes a single operation within the queue .
/* Deliberately ignore JSON parsing errors */
A task that returns true
A task that returns true
operation
TableOperation
The operation to execute.
The operation to execute .
batch
OperationBatch
The operation batch being executed.
The operation batch being executed .
removeFromQueueOnSuccess
bool
None
cancellationToken
CancellationToken
A  to observe.
A to observe .