internal InstancePersistenceContext (InstanceHandle handle, InstanceView view) { if (handle == null) throw new ArgumentNullException ("handle"); if (view == null) throw new ArgumentNullException ("view"); InstanceHandle = handle; InstanceView = view; }
internal InstancePersistenceEvent AddHandleToEvent(InstanceHandle handle, InstancePersistenceEvent persistenceEvent, InstanceOwner owner) { lock (this.ThisLock) { InstanceNormalEvent ownerEventHelper = this.GetOwnerEventHelper(persistenceEvent, owner); ownerEventHelper.BoundHandles.Add(handle); ownerEventHelper.PendingHandles.Remove(handle); return (ownerEventHelper.IsSignaled ? ownerEventHelper : null); } }
public IAsyncResult BeginWaitForEvents(InstanceHandle handle, TimeSpan timeout, AsyncCallback callback, object state) { if (handle == null) { throw Fx.Exception.ArgumentNull("handle"); } if (!object.ReferenceEquals(this, handle.Store)) { throw Fx.Exception.Argument("handle", SRCore.ContextNotFromThisStore); } TimeoutHelper.ThrowIfNegativeArgument(timeout); return InstanceHandle.BeginWaitForEvents(handle, timeout, callback, state); }
InstancePersistenceContext(InstanceHandle handle) { Fx.Assert(handle != null, "Null handle passed to InstancePersistenceContext."); InstanceHandle = handle; // Fork a copy of the current view to be the new working view. It starts with no query results. InstanceView newView = handle.View.Clone(); newView.InstanceStoreQueryResults = null; InstanceView = newView; this.cancellationHandlerCalled = 0; }
// This can be called to remove a handle from the BoundHandles table. It should be called only after no more commands are in progress or could be made on the handle. internal void Unbind(InstanceHandle handle) { Fx.Assert(object.ReferenceEquals(this, handle.Owner), "Unbind called on the wrong owner for a handle."); Fx.Assert(handle.Id != Guid.Empty, "Unbind called on a handle not even bound to an instance."); lock (HandlesLock) { // The handle may have already been bumped - only remove it if it's still it. InstanceHandle existingHandle; if (BoundHandles.TryGetValue(handle.Id, out existingHandle) && object.ReferenceEquals(handle, existingHandle)) { BoundHandles.Remove(handle.Id); } } }
internal InstancePersistenceContext(InstanceHandle handle, Transaction transaction) : this(handle) { Fx.Assert(transaction != null, "Null Transaction passed to InstancePersistenceContext."); // Let's take our own clone of the transaction. We need to do this because we might need to // create a TransactionScope using the transaction and in cases where we are dealing with a // transaction that is flowed into the workflow on a message, the DependentTransaction that the // dispatcher creates and sets to Transaction.Current may already be Completed by the time a // Save operation is done. And since TransactionScope creates a DependentTransaction, it won't // be able to. // We don't create another DependentClone because we are going to do a EnlistVolatile on the // transaction ourselves. this.transaction = transaction.Clone(); IsHostTransaction = true; this.eventTraceActivity = handle.EventTraceActivity; }
public IAsyncResult BeginExecute(InstanceHandle handle, InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state) { if (command == null) { throw Fx.Exception.ArgumentNull("command"); } if (handle == null) { throw Fx.Exception.ArgumentNull("handle"); } if (!object.ReferenceEquals(this, handle.Store)) { throw Fx.Exception.Argument("handle", SRCore.ContextNotFromThisStore); } TimeoutHelper.ThrowIfNegativeArgument(timeout); return InstancePersistenceContext.BeginOuterExecute(handle, command, Transaction.Current, timeout, callback, state); }
public void MarkInstanceOwnerCreated(Guid lockOwnerId, long surrogateLockOwnerId, InstanceHandle lockOwnerInstanceHandle, bool detectRunnableInstances, bool detectActivatableInstances) { this.lockOwnerId = lockOwnerId; this.SurrogateLockOwnerId = surrogateLockOwnerId; this.lockOwnerInstanceHandle = new WeakReference(lockOwnerInstanceHandle); TimeSpan hostLockRenewalPeriod = this.sqlWorkflowInstanceStore.HostLockRenewalPeriod; TimeSpan runnableInstancesDetectionPeriod = this.sqlWorkflowInstanceStore.RunnableInstancesDetectionPeriod; if (detectActivatableInstances) { this.InstanceDetectionTask = new DetectActivatableWorkflowsTask(this.sqlWorkflowInstanceStore, this, runnableInstancesDetectionPeriod); } else if (detectRunnableInstances) { this.InstanceDetectionTask = new DetectRunnableInstancesTask(this.sqlWorkflowInstanceStore, this, runnableInstancesDetectionPeriod); } this.LockRenewalTask = new System.Activities.DurableInstancing.LockRenewalTask(this.sqlWorkflowInstanceStore, this, hostLockRenewalPeriod); this.LockRecoveryTask = new System.Activities.DurableInstancing.LockRecoveryTask(this.sqlWorkflowInstanceStore, this, hostLockRenewalPeriod); if (this.InstanceDetectionTask != null) { this.InstanceDetectionTask.ResetTimer(true); } this.LockRenewalTask.ResetTimer(true); this.LockRecoveryTask.ResetTimer(true); }
bool CreateDirectory() { this.instanceManager.InitializePersistenceProviderDirectory(); this.instanceManager.handle = this.handle; this.handle = null; return true; }
public void Open(TimeSpan timeout) { Fx.Assert(Host != null, "Extension should have been attached in WorkflowServiceHost constructor."); lock (this.thisLock) { ThrowIfDisposedOrImmutable(this.state); this.state = States.Opened; } InitializeDefinitionProvider(); CheckPersistenceProviderBehavior(); SetDefaultOwnerMetadata(); if (InstanceStore != null) { using (new TransactionScope(TransactionScopeOption.Suppress)) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); InstanceHandle handle = null; try { handle = InstanceStore.CreateInstanceHandle(null); this.owner = InstanceStore.Execute(handle, GetCreateOwnerCommand(), timeoutHelper.RemainingTime()).InstanceOwner; this.handle = handle; handle = null; } catch (InstancePersistenceException exception) { throw FxTrace.Exception.AsError(new CommunicationException(SR.UnableToOpenAndRegisterStore, exception)); } finally { if (handle != null) { handle.Free(); } } } } InitializePersistenceProviderDirectory(); }
public OpenInstanceStoreAsyncResult(DurableInstanceManager instanceManager, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.instanceManager = instanceManager; this.timeoutHelper = new TimeoutHelper(timeout); lock (this.instanceManager.thisLock) { DurableInstanceManager.ThrowIfDisposedOrImmutable(this.instanceManager.state); this.instanceManager.state = States.Opened; } this.instanceManager.InitializeDefinitionProvider(); instanceManager.CheckPersistenceProviderBehavior(); this.instanceManager.SetDefaultOwnerMetadata(); this.OnCompleting = OpenInstanceStoreAsyncResult.onFinally; bool completeSelf; Exception completionException = null; try { if (instanceManager.InstanceStore == null) { completeSelf = CreateDirectory(); } else { this.handle = this.instanceManager.InstanceStore.CreateInstanceHandle(null); IAsyncResult executeResult = this.instanceManager.InstanceStore.BeginExecute(this.handle, this.instanceManager.GetCreateOwnerCommand(), this.timeoutHelper.RemainingTime(), this.PrepareAsyncCompletion(OpenInstanceStoreAsyncResult.handleEndExecute), this); completeSelf = SyncContinue(executeResult); } } catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } completionException = exception; completeSelf = true; } if (completeSelf) { Complete(true, completionException); } }
protected override object OnNewInstanceHandle(InstanceHandle instanceHandle) { this.MakeReadOnly(); return new InstanceLockTracking(this); }
AcquireContextAsyncResult(InstanceHandle handle, Transaction hostTransaction, TimeSpan timeout, out bool setOperationPending, bool synchronous, AsyncCallback callback, object state) : base(callback, state) { // Need to report back to the caller whether or not we set OperationPending. setOperationPending = false; this.handle = handle; HostTransaction = hostTransaction; this.timeoutHelper = new TimeoutHelper(timeout); AcquireContextAsyncResult transactionWait; bool reuseContext = false; lock (this.handle.ThisLock) { if (!this.handle.IsValid) { throw Fx.Exception.AsError(new OperationCanceledException(SRCore.HandleFreed)); } if (this.handle.OperationPending) { throw Fx.Exception.AsError(new InvalidOperationException(SRCore.CommandExecutionCannotOverlap)); } setOperationPending = true; this.handle.OperationPending = true; transactionWait = this.handle.CurrentTransactionalAsyncResult; if (transactionWait != null) { Fx.Assert(this.handle.AcquirePending == null, "Overlapped acquires pending."); // If the transaction matches but is already completed (or completing), the easiest ting to do // is wait for it to complete, then try to re-enlist, and have that failure be the failure mode for Execute. // We do that by following the regular, non-matching transaction path. if (transactionWait.HostTransaction.Equals(hostTransaction) && !this.handle.TooLateToEnlist) { reuseContext = true; this.executionContext = transactionWait.ReuseContext(); this.handle.CurrentExecutionContext = this.executionContext; } else { this.handle.AcquirePending = this; } } } if (transactionWait != null) { Fx.Assert(transactionWait.IsCompleted, "Old AsyncResult must be completed by now."); // Reuse the existing InstanceExecutionContext if this is the same transaction we're waiting for. if (reuseContext) { Complete(true); return; } TimeSpan waitTimeout = this.timeoutHelper.RemainingTime(); if (synchronous) { if (!transactionWait.WaitForHostTransaction.Wait(waitTimeout)) { throw Fx.Exception.AsError(new TimeoutException(InternalSR.TimeoutOnOperation(waitTimeout))); } } else { if (!transactionWait.WaitForHostTransaction.WaitAsync(AcquireContextAsyncResult.onHostTransaction, this, waitTimeout)) { return; } } } if (DoAfterTransaction()) { Complete(true); } }
public OpenInstanceStoreAsyncResult(DurableInstanceManager instanceManager, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { bool flag; this.instanceManager = instanceManager; this.timeoutHelper = new TimeoutHelper(timeout); lock (this.instanceManager.thisLock) { DurableInstanceManager.ThrowIfDisposedOrImmutable(this.instanceManager.state); this.instanceManager.state = 1; } instanceManager.CheckPersistenceProviderBehavior(); this.instanceManager.SetDefaultOwnerMetadata(); base.OnCompleting = onFinally; Exception exception = null; try { if (instanceManager.InstanceStore == null) { flag = this.CreateDirectory(); } else { this.handle = this.instanceManager.InstanceStore.CreateInstanceHandle((InstanceOwner) null); IAsyncResult result = this.instanceManager.InstanceStore.BeginExecute(this.handle, this.instanceManager.createOwnerCommand, this.timeoutHelper.RemainingTime(), base.PrepareAsyncCompletion(handleEndExecute), this); flag = base.SyncContinue(result); } } catch (Exception exception2) { if (Fx.IsFatal(exception2)) { throw; } exception = exception2; flag = true; } if (flag) { base.Complete(true, exception); } }
protected override void OnFreeInstanceHandle(InstanceHandle instanceHandle, object userContext) { ((InstanceLockTracking) userContext).HandleFreed(); }
private static void WaitForRunnableInstance(InstanceStore store, InstanceHandle ownerHandle) { IEnumerable<InstancePersistenceEvent> events = store.WaitForEvents(ownerHandle, TimeSpan.MaxValue); bool foundRunnable = false; // Loop through the persistence events looking for the HasRunnableWorkflow event (in this sample, it corresponds with // the workflow instance whose timer has expired and is ready to be resumed by the host). foreach (InstancePersistenceEvent persistenceEvent in events) { if (persistenceEvent.Equals(HasRunnableWorkflowEvent.Value)) { foundRunnable = true; break; } } if (!foundRunnable) { throw new ApplicationException("Unexpected: No runnable instances found in the instance store"); } }
public ExecuteAsyncResult(InstanceHandle initialInstanceHandle, InstancePersistenceCommand command, Transaction transaction, TimeSpan timeout, AsyncCallback callback, object state) : this(command, timeout, callback, state) { this.initialInstanceHandle = initialInstanceHandle; OnCompleting = new Action<AsyncResult, Exception>(SimpleCleanup); IAsyncResult result = this.initialInstanceHandle.BeginAcquireExecutionContext(transaction, this.timeoutHelper.RemainingTime(), PrepareAsyncCompletion(ExecuteAsyncResult.onAcquireContext), this); if (result.CompletedSynchronously) { // After this stage, must complete explicitly in order to get Cleanup to run correctly. bool completeSelf = false; Exception completionException = null; try { completeSelf = OnAcquireContext(result); } catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } completeSelf = true; completionException = exception; } if (completeSelf) { Complete(true, completionException); } } }
public AcquireContextAsyncResult(InstanceHandle handle, Transaction hostTransaction, TimeSpan timeout, out bool setOperationPending, AsyncCallback callback, object state) : this(handle, hostTransaction, timeout, out setOperationPending, false, callback, state) { }
internal static IAsyncResult BeginWaitForEvents(InstanceHandle handle, TimeSpan timeout, AsyncCallback callback, object state) { return new WaitForEventsAsyncResult(handle, timeout, callback, state); }
internal InstancePersistenceContext(InstanceHandle handle, TimeSpan timeout) : this(handle) { this.timeout = timeout; }
public void Open(TimeSpan timeout) { lock (this.thisLock) { ThrowIfDisposedOrImmutable(this.state); this.state = 1; } this.CheckPersistenceProviderBehavior(); this.SetDefaultOwnerMetadata(); if (this.InstanceStore != null) { using (new TransactionScope(TransactionScopeOption.Suppress)) { TimeoutHelper helper = new TimeoutHelper(timeout); InstanceHandle handle = null; try { handle = this.InstanceStore.CreateInstanceHandle((InstanceOwner) null); this.owner = this.InstanceStore.Execute(handle, this.createOwnerCommand, helper.RemainingTime()).InstanceOwner; this.handle = handle; handle = null; } catch (InstancePersistenceException exception) { throw System.ServiceModel.Activities.FxTrace.Exception.AsError(new CommunicationException(System.ServiceModel.Activities.SR.UnableToOpenAndRegisterStore, exception)); } finally { if (handle != null) { handle.Free(); } } } } this.InitializePersistenceProviderDirectory(); }
public ExecuteAsyncResult(InstanceHandle initialInstanceHandle, InstancePersistenceCommand command, Transaction transaction, TimeSpan timeout) : this(command, timeout, null, null) { this.initialInstanceHandle = initialInstanceHandle; this.context = this.initialInstanceHandle.AcquireExecutionContext(transaction, this.timeoutHelper.RemainingTime()); Exception completionException = null; try { // After this stage, must complete explicitly in order to get Cleanup to run correctly. this.context.RootAsyncResult = this; this.context.LastAsyncResult = this; OnCompleting = new Action<AsyncResult, Exception>(Cleanup); RunLoopCore(true); if (this.transactionToCommit != null) { try { this.transactionToCommit.Commit(); } catch (TransactionException) { // Since we are enlisted in this transaction, we can ignore exceptions from Commit. } this.transactionToCommit = null; } DoWaitForTransaction(true); } catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } completionException = exception; } Complete(true, completionException); }
bool PostProcess() { //cleanup any buffered receives unassociated with workflowServiceInstances BufferedReceiveManager bufferedReceiveManager = this.instanceManager.Host.Extensions.Find<BufferedReceiveManager>(); if (bufferedReceiveManager != null) { bufferedReceiveManager.AbandonBufferedReceives(); } // Send the DeleteWorkflowOwner command to the instance store. if (this.instanceManager.InstanceStore != null) { IAsyncResult executeResult = null; this.handle = this.instanceManager.InstanceStore.CreateInstanceHandle(this.instanceManager.owner); try { executeResult = this.instanceManager.InstanceStore.BeginExecute(this.handle, new DeleteWorkflowOwnerCommand(), this.timeoutHelper.RemainingTime(), this.PrepareAsyncCompletion(CloseAsyncResult.handleEndExecute), this); return (SyncContinue(executeResult)); } // Ignore some exceptions because DeleteWorkflowOwner is best effort. catch (InstancePersistenceCommandException) { } catch (InstanceOwnerException) { } catch (OperationCanceledException) { } finally { if (executeResult == null) { this.handle.Free(); this.handle = null; } } return this.SyncContinue(executeResult); } else { CloseProviderDirectory(); return true; } }
public void MarkInstanceOwnerCreated(Guid lockOwnerId, long surrogateLockOwnerId, InstanceHandle lockOwnerInstanceHandle, bool detectRunnableInstances, bool detectActivatableInstances) { Fx.Assert(this.isBeingModified, "Must have modification lock to mark owner as created"); this.lockOwnerId = lockOwnerId; this.SurrogateLockOwnerId = surrogateLockOwnerId; this.lockOwnerInstanceHandle = new WeakReference(lockOwnerInstanceHandle); TimeSpan runnableInstancesDetectionPeriod = this.sqlWorkflowInstanceStore.RunnableInstancesDetectionPeriod; if (detectActivatableInstances) { this.InstanceDetectionTask = new DetectActivatableWorkflowsTask(this.sqlWorkflowInstanceStore, this, runnableInstancesDetectionPeriod); } else if (detectRunnableInstances) { this.InstanceDetectionTask = new DetectRunnableInstancesTask(this.sqlWorkflowInstanceStore, this, runnableInstancesDetectionPeriod); } // By setting taskTimeout value with BufferedHostLockRenewalPeriod, // BufferedHostLockRenewalPeriod becomes max sql retry duration for ExtendLock command and RecoveryIntanceLock command. this.LockRenewalTask = new LockRenewalTask(this.sqlWorkflowInstanceStore, this, this.HostLockRenewalPulseInterval, this.sqlWorkflowInstanceStore.BufferedHostLockRenewalPeriod); this.LockRecoveryTask = new LockRecoveryTask(this.sqlWorkflowInstanceStore, this, this.HostLockRenewalPulseInterval, this.sqlWorkflowInstanceStore.BufferedHostLockRenewalPeriod); if (this.InstanceDetectionTask != null) { this.InstanceDetectionTask.ResetTimer(true); } this.LockRenewalTask.ResetTimer(true); this.LockRecoveryTask.ResetTimer(true); }
public AcquireContextAsyncResult(InstanceHandle handle, Transaction hostTransaction, TimeSpan timeout, out bool setOperationPending) : this(handle, hostTransaction, timeout, out setOperationPending, true, null, null) { }
private bool Process() { while (this.workflowServiceInstances.MoveNext()) { this.currentInstance = this.workflowServiceInstances.Current.GetInstance(null); if (this.currentInstance != null) { IAsyncResult result = this.currentInstance.BeginReleaseInstance(false, this.timeoutHelper.RemainingTime(), base.PrepareAsyncCompletion(handleEndReleaseInstance), this); if (!base.CheckSyncContinue(result)) { return false; } this.currentInstance.EndReleaseInstance(result); } } BufferedReceiveManager manager = this.instanceManager.Host.Extensions.Find<BufferedReceiveManager>(); if (manager != null) { manager.AbandonBufferedReceives(); } if (this.instanceManager.InstanceStore == null) { return this.CloseProviderDirectory(); } IAsyncResult result2 = null; this.handle = this.instanceManager.InstanceStore.CreateInstanceHandle(this.instanceManager.owner); try { result2 = this.instanceManager.InstanceStore.BeginExecute(this.handle, new DeleteWorkflowOwnerCommand(), this.timeoutHelper.RemainingTime(), base.PrepareAsyncCompletion(handleEndExecute), this); } catch (InstancePersistenceCommandException) { } catch (InstanceOwnerException) { } catch (OperationCanceledException) { } finally { if (result2 == null) { this.handle.Free(); this.handle = null; } } return base.SyncContinue(result2); }
private AcquireContextAsyncResult(InstanceHandle handle, Transaction hostTransaction, TimeSpan timeout, out bool setOperationPending, bool synchronous, AsyncCallback callback, object state) : base(callback, state) { InstanceHandle.AcquireContextAsyncResult currentTransactionalAsyncResult; setOperationPending = false; this.handle = handle; this.HostTransaction = hostTransaction; this.timeoutHelper = new TimeoutHelper(timeout); bool flag = false; lock (this.handle.ThisLock) { if (!this.handle.IsValid) { throw Fx.Exception.AsError(new OperationCanceledException(SRCore.HandleFreed)); } if (this.handle.OperationPending) { throw Fx.Exception.AsError(new InvalidOperationException(SRCore.CommandExecutionCannotOverlap)); } setOperationPending = true; this.handle.OperationPending = true; currentTransactionalAsyncResult = this.handle.CurrentTransactionalAsyncResult; if (currentTransactionalAsyncResult != null) { if (currentTransactionalAsyncResult.HostTransaction.Equals(hostTransaction) && !this.handle.TooLateToEnlist) { flag = true; this.executionContext = currentTransactionalAsyncResult.ReuseContext(); this.handle.CurrentExecutionContext = this.executionContext; } else { this.handle.AcquirePending = this; } } } if (currentTransactionalAsyncResult != null) { if (flag) { base.Complete(true); return; } TimeSpan span = this.timeoutHelper.RemainingTime(); if (synchronous) { if (!currentTransactionalAsyncResult.WaitForHostTransaction.Wait(span)) { throw Fx.Exception.AsError(new TimeoutException(SRCore.TimeoutOnOperation(span))); } } else if (!currentTransactionalAsyncResult.WaitForHostTransaction.WaitAsync(onHostTransaction, this, span)) { return; } } if (this.DoAfterTransaction()) { base.Complete(true); } }
internal static InstanceView OuterExecute(InstanceHandle initialInstanceHandle, InstancePersistenceCommand command, Transaction transaction, TimeSpan timeout) { try { return ExecuteAsyncResult.End(new ExecuteAsyncResult(initialInstanceHandle, command, transaction, timeout)); } catch (TimeoutException) { initialInstanceHandle.Free(); throw; } catch (OperationCanceledException) { initialInstanceHandle.Free(); throw; } }
internal WaitForEventsAsyncResult(InstanceHandle handle, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.handle = handle; this.timeout = timeout; if ((this.timeout != TimeSpan.Zero) && (this.timeout != TimeSpan.MaxValue)) { this.timer = new IOThreadTimer(timeoutCallback, this, false); } List<InstancePersistenceEvent> list = this.handle.StartWaiting(this, this.timer, this.timeout); if (list == null) { if (this.timeout == TimeSpan.Zero) { this.handle.CancelWaiting(this); throw Fx.Exception.AsError(new TimeoutException(SRCore.WaitForEventsTimedOut(TimeSpan.Zero))); } } else { this.readyEvents = list; base.Complete(true); } }
internal static IAsyncResult BeginOuterExecute(InstanceHandle initialInstanceHandle, InstancePersistenceCommand command, Transaction transaction, TimeSpan timeout, AsyncCallback callback, object state) { try { return new ExecuteAsyncResult(initialInstanceHandle, command, transaction, timeout, callback, state); } catch (TimeoutException) { initialInstanceHandle.Free(); throw; } catch (OperationCanceledException) { initialInstanceHandle.Free(); throw; } }