static ServiceDurableInstance GetInstanceContextExtension() { OperationContext operationContext = OperationContext.Current; if (operationContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException( SR2.GetString( SR2.OnlyCallableFromServiceOperation, typeof(DurableOperationContext).Name))); } IsInOperation isInOperation = operationContext.Extensions.Find <IsInOperation>(); if (isInOperation == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException( SR2.GetString( SR2.OnlyCallableWhileInOperation, typeof(DurableOperationContext).Name))); } InstanceContext currentInstanceContext = operationContext.InstanceContext; if (currentInstanceContext == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException( SR2.GetString( SR2.OnlyCallableFromServiceOperation, typeof(DurableOperationContext).Name))); } ServiceDurableInstance durableInstance = currentInstanceContext.Extensions.Find <ServiceDurableInstance>(); if (durableInstance == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException( SR2.GetString( SR2.OnlyCallableFromDurableService, typeof(DurableOperationContext).Name, typeof(DurableServiceAttribute).Name))); } return(durableInstance); }
public StartOperationScope(ServiceDurableInstance durableInstance) { this.durableInstance = durableInstance; this.durableInstance.runtimeValidator.ValidateRuntime(); DurableOperationContext.BeginOperation(); // No need for Interlocked because we don't support // ConcurrencyMode.Multiple this.durableInstance.outstandingOperations++; if (this.durableInstance.saveStateInOperationTransaction && Transaction.Current != null) { this.durableInstance.clonedTransaction = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete); } }
public object Invoke(object instance, object[] inputs, out object[] outputs) { if (instance == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("instance"); } ServiceDurableInstance durableInstance = instance as ServiceDurableInstance; if (durableInstance == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException( SR2.GetString(SR2.InvokeCalledWithWrongType, typeof(DurableServiceAttribute).Name))); } object serviceInstance = durableInstance.StartOperation(this.canCreateInstance); Exception operationException = null; bool failFast = false; try { return(this.innerInvoker.Invoke(serviceInstance, inputs, out outputs)); } catch (Exception e) { if (Fx.IsFatal(e)) { failFast = true; throw; } operationException = e; ServiceErrorHandler.MarkException(e); throw; } finally { if (!failFast) { durableInstance.FinishOperation(this.completesInstance, this.contractCausesSave, operationException); } } }
public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state) { if (instance == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("instance"); } ServiceDurableInstance durableInstance = instance as ServiceDurableInstance; if (durableInstance == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException( SR2.GetString(SR2.InvokeCalledWithWrongType, typeof(DurableServiceAttribute).Name))); } return(new InvokeAsyncResult(durableInstance, inputs, this, this.canCreateInstance, callback, state)); }
public InvokeAsyncResult(ServiceDurableInstance instance, object[] inputs, ServiceOperationInvoker invoker, bool canCreateInstance, AsyncCallback callback, object state) : base(callback, state) { this.invoker = invoker; this.inputs = inputs; this.durableInstance = instance; this.operationContext = OperationContext.Current; IAsyncResult result = this.durableInstance.BeginStartOperation(canCreateInstance, startCallback, this); if (result.CompletedSynchronously) { this.serviceInstance = this.durableInstance.EndStartOperation(result); if (DoInvoke()) { Complete(true, this.completionException); } } }
public StartOperationAsyncResult(ServiceDurableInstance durableInstance, bool canCreateInstance, AsyncCallback callback, object state) : base(callback, state) { this.durableInstance = durableInstance; bool completeSelf = false; IAsyncResult result = null; this.operationContext = OperationContext.Current; scope = new StartOperationScope(this.durableInstance); bool success = false; try { if (this.durableInstance.instance == null) { if (this.durableInstance.TryActivateInstance(canCreateInstance)) { completeSelf = true; } else { using (PersistenceScope persistenceScope = new PersistenceScope( this.durableInstance.saveStateInOperationTransaction, this.durableInstance.clonedTransaction)) { if (this.durableInstance.lockingProvider != null) { result = this.durableInstance.lockingProvider.BeginLoad(this.durableInstance.operationTimeout, true, loadCallback, this); } else { result = this.durableInstance.provider.BeginLoad(this.durableInstance.operationTimeout, loadCallback, this); } } this.durableInstance.existsInPersistence = true; if (result.CompletedSynchronously) { completeSelf = true; } } } else { completeSelf = true; } success = true; } finally { if (!success) { scope.Dispose(); } } if (completeSelf) { try { if (result != null) { this.durableInstance.instance = this.durableInstance.provider.EndLoad(result); } Fx.Assert(this.durableInstance.instance != null, "The instance should always be set here."); Complete(true); scope.Complete(); } finally { scope.Dispose(); } } }
public FinishOperationAsyncResult(ServiceDurableInstance durableInstance, bool completeInstance, bool performPersistence, Exception operationException, AsyncCallback callback, object state) : base(callback, state) { this.durableInstance = durableInstance; IAsyncResult result = null; OperationType operation = OperationType.None; bool completeSelf = false; bool disposeInstace; operation = this.durableInstance.FinishOperationCommon(completeInstance, operationException, out disposeInstace); if (performPersistence) { switch (operation) { case OperationType.Unlock: if (this.durableInstance.lockingProvider != null) { using (PersistenceScope scope = new PersistenceScope( this.durableInstance.saveStateInOperationTransaction, this.durableInstance.clonedTransaction)) { result = this.durableInstance.lockingProvider.BeginUnlock(this.durableInstance.operationTimeout, unlockCallback, this); } } break; case OperationType.Delete: using (PersistenceScope scope = new PersistenceScope( this.durableInstance.saveStateInOperationTransaction, this.durableInstance.clonedTransaction)) { result = this.durableInstance.provider.BeginDelete(this.durableInstance.Instance, this.durableInstance.operationTimeout, deleteCallback, this); } break; case OperationType.Create: using (PersistenceScope scope = new PersistenceScope( this.durableInstance.saveStateInOperationTransaction, this.durableInstance.clonedTransaction)) { if (this.durableInstance.lockingProvider != null) { result = this.durableInstance.lockingProvider.BeginCreate(this.durableInstance.Instance, this.durableInstance.operationTimeout, disposeInstace, createCallback, this); } else { result = this.durableInstance.provider.BeginCreate(this.durableInstance.Instance, this.durableInstance.operationTimeout, createCallback, this); } } break; case OperationType.Update: using (PersistenceScope scope = new PersistenceScope( this.durableInstance.saveStateInOperationTransaction, this.durableInstance.clonedTransaction)) { if (this.durableInstance.lockingProvider != null) { result = this.durableInstance.lockingProvider.BeginUpdate(this.durableInstance.Instance, this.durableInstance.operationTimeout, disposeInstace, updateCallback, this); } else { result = this.durableInstance.provider.BeginUpdate(this.durableInstance.Instance, this.durableInstance.operationTimeout, updateCallback, this); } } break; case OperationType.None: break; default: Fx.Assert("Unknown OperationType was passed in."); break; } } if (disposeInstace) { this.durableInstance.DisposeInstance(); } if (operation == OperationType.None || (result != null && result.CompletedSynchronously)) { completeSelf = true; } if (!performPersistence) { Fx.Assert(result == null, "Should not have had a result if we didn't perform persistence."); Complete(true); return; } if (completeSelf) { CallEndOperation(operation, result); Complete(true); } }
public static void CompleteInstance() { ServiceDurableInstance durableInstance = GetInstanceContextExtension(); durableInstance.MarkForCompletion(); }
public static void AbortInstance() { ServiceDurableInstance durableInstance = GetInstanceContextExtension(); durableInstance.AbortInstance(); }