예제 #1
2
        protected override IAsyncResult BeginTryCommand(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state)
        {
            StructuredTracer.Correlate();

            try
            {
                if (command is SaveWorkflowCommand)
                {
                    return new TypedCompletedAsyncResult<bool>(SaveWorkflow(context, (SaveWorkflowCommand)command), callback, state);
                }
                else if (command is LoadWorkflowCommand)
                {
                    return new TypedCompletedAsyncResult<bool>(LoadWorkflow(context, (LoadWorkflowCommand)command), callback, state);
                }
                else if (command is CreateWorkflowOwnerCommand)
                {
                    return new TypedCompletedAsyncResult<bool>(CreateWorkflowOwner(context, (CreateWorkflowOwnerCommand)command), callback, state);
                }
                else if (command is DeleteWorkflowOwnerCommand)
                {
                    return new TypedCompletedAsyncResult<bool>(DeleteWorkflowOwner(context, (DeleteWorkflowOwnerCommand)command), callback, state);
                }
                return new TypedCompletedAsyncResult<bool>(false, callback, state);
            }
            catch (Exception e)
            {
                return new TypedCompletedAsyncResult<Exception>(e, callback, state);
            }
        }
        private IAsyncResult CreateWorkflowOwner(InstancePersistenceContext context, CreateWorkflowOwnerCommand command, TimeSpan timeout, AsyncCallback callback, object state)
        {            
            var owner = new LockOwner()
            {
                Id = Guid.NewGuid(),                
            };

            // TODO: map fields into the owner entity
            Debug.WriteLine("CreateWorkflowOwner::InstanceOwnerMetadata: ");
            Debug.Indent();
            foreach (var key in command.InstanceOwnerMetadata.Keys)
            {
                Debug.WriteLine("[{0}]=[{1}]", key, command.InstanceOwnerMetadata[key].Value);
            }            
            Debug.Unindent();
            


            //context.BindInstanceOwner(owner.Id, owner.Id);
            //context.BindEvent(HasRunnableWorkflowEvent.Value);

            //return new CompletedAsyncResult(callback, state);

            return null;
        }
 public TryLoadRunnableWorkflowAsyncResult(InstancePersistenceContext context, InstancePersistenceCommand command, SqlWorkflowInstanceStore store, SqlWorkflowInstanceStoreLock storeLock, Transaction currentTransaction, TimeSpan timeout, AsyncCallback callback, object state) : base(context, command, store, storeLock, currentTransaction, timeout, callback, state)
 {
     if (base.Store.WorkflowHostType == Guid.Empty)
     {
         throw FxTrace.Exception.AsError(new InstancePersistenceCommandException(command.Name, System.Activities.DurableInstancing.SR.TryLoadRequiresWorkflowType, null));
     }
 }
예제 #4
0
        //The persistence engine will send a variety of commands to the configured InstanceStore,
        //such as CreateWorkflowOwnerCommand, SaveWorkflowCommand, and LoadWorkflowCommand.
        //This method is where we will handle those commands
        protected override IAsyncResult BeginTryCommand(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state)
        {
            IDictionary<XName, InstanceValue> data;

            //The CreateWorkflowOwner command instructs the instance store to create a new instance owner bound to the instanace handle
            if (command is CreateWorkflowOwnerCommand)
            {
                context.BindInstanceOwner(this.ownerInstanceId, Guid.NewGuid());
            }
            //The SaveWorkflow command instructs the instance store to modify the instance bound to the instance handle or an instance key
            else if (command is SaveWorkflowCommand)
            {
                var saveCommand = (SaveWorkflowCommand)command;
                data = saveCommand.InstanceData;

                this.Save(data);
            }
            //The LoadWorkflow command instructs the instance store to lock and load the instance bound to the identifier in the instance handle
            else if (command is LoadWorkflowCommand)
            {
                var fileName = IoHelper.GetFileName(this.ownerInstanceId);

                using (var inputStream = new FileStream(fileName, FileMode.Open))
                {
                    data = LoadInstanceDataFromFile(inputStream);
                    //load the data into the persistence Context
                    context.LoadedInstance(InstanceState.Initialized, data, null, null, null);
                }
            }

            return new CompletedAsyncResult<bool>(true, callback, state);
        }
        protected override IAsyncResult BeginTryCommand(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state)
        {
            if(context == null) throw new ArgumentNullException("context");
            if(command == null) throw new ArgumentNullException("command");

            // Log which commands we are receiving
            Debug.WriteLine("InstanceStore::BeginTryCommand::{0} received", command.GetType().Name);

            IAsyncResult result = null;  
            
            // validate the store lock
                      
            if (command is CreateWorkflowOwnerCommand)
            {
                result = CreateWorkflowOwner(context, (CreateWorkflowOwnerCommand) command, timeout, callback, state);
            }
                        
            if (result == null)
            {
                // Log which commands we are not handling
                Debug.WriteLine("InstanceStore::BeginTryCommand::{0} was not implemented", command.GetType().Name);

                // The base.BeginTryCommand will return a false (unhandled) return value
                return base.BeginTryCommand(context, command, timeout, callback, state);
            }
            return result;
        }
 public SaveWorkflowAsyncResult(InstancePersistenceContext context, InstancePersistenceCommand command, SqlWorkflowInstanceStore store, SqlWorkflowInstanceStoreLock storeLock, Transaction currentTransaction, TimeSpan timeout, AsyncCallback callback, object state) : base(context, command, store, storeLock, currentTransaction, timeout, callback, state)
 {
     if (((SaveWorkflowCommand) command).InstanceKeyMetadataChanges.Count > 0)
     {
         throw FxTrace.Exception.AsError(new InstancePersistenceCommandException(System.Activities.DurableInstancing.SR.InstanceKeyMetadataChangesNotSupported));
     }
 }
예제 #7
0
 public LoadRetryAsyncResult(SqlWorkflowInstanceStore store, System.Runtime.DurableInstancing.InstancePersistenceContext context, System.Runtime.DurableInstancing.InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state)
 {
     this.InstanceStore = store;
     this.InstancePersistenceContext = context;
     this.InstancePersistenceCommand = command;
     this.commandTimeout             = new TimeoutHelper(timeout);
     this.InstanceStore.BeginTryCommandInternal(this.InstancePersistenceContext, this.InstancePersistenceCommand, this.commandTimeout.RemainingTime(), onTryCommandCallback, this);
 }
예제 #8
0
 protected internal virtual IAsyncResult BeginTryCommand(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state)
 {
     if (try_command_delegate == null)
     {
         try_command_delegate = new Func <InstancePersistenceContext, InstancePersistenceCommand, TimeSpan, bool> (TryCommand);
     }
     return(try_command_delegate.BeginInvoke(context, command, timeout, callback, state));
 }
 internal IAsyncResult BeginTryCommandInternal(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state)
 {
     SqlWorkflowInstanceStoreAsyncResult result = null;
     if (command is SaveWorkflowCommand)
     {
         result = new SaveWorkflowAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
     }
     else if (command is TryLoadRunnableWorkflowCommand)
     {
         result = new TryLoadRunnableWorkflowAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
     }
     else if (command is LoadWorkflowCommand)
     {
         result = new LoadWorkflowAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
     }
     else if (command is LoadWorkflowByInstanceKeyCommand)
     {
         result = new LoadWorkflowByKeyAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
     }
     else if (command is ExtendLockCommand)
     {
         result = new ExtendLockAsyncResult(null, command, this, this.storeLock, null, timeout, callback, state);
     }
     else if (command is DetectRunnableInstancesCommand)
     {
         result = new DetectRunnableInstancesAsyncResult(null, command, this, this.storeLock, null, timeout, callback, state);
     }
     else if (command is DetectActivatableWorkflowsCommand)
     {
         result = new DetectActivatableWorkflowsAsyncResult(null, command, this, this.storeLock, null, timeout, callback, state);
     }
     else if (command is RecoverInstanceLocksCommand)
     {
         result = new RecoverInstanceLocksAsyncResult(null, command, this, this.storeLock, null, timeout, callback, state);
     }
     else if (command is UnlockInstanceCommand)
     {
         result = new UnlockInstanceAsyncResult(null, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
     }
     else if (command is CreateWorkflowOwnerCommand)
     {
         result = new CreateWorkflowOwnerAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
     }
     else if (command is DeleteWorkflowOwnerCommand)
     {
         result = new DeleteWorkflowOwnerAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
     }
     else if (command is QueryActivatableWorkflowsCommand)
     {
         result = new QueryActivatableWorkflowAsyncResult(context, command, this, this.storeLock, Transaction.Current, timeout, callback, state);
     }
     else
     {
         return base.BeginTryCommand(context, command, timeout, callback, state);
     }
     result.ScheduleCallback();
     return result;
 }
예제 #10
0
        protected override IAsyncResult BeginTryCommand(
            InstancePersistenceContext context,
            InstancePersistenceCommand command,
            TimeSpan timeout, AsyncCallback callback, object state)
        {

            switch(command.GetType().Name)
            {
                case "CreateWorkflowOwnerCommand":

                    Func<Exception> createFunc = () => ProcessCreateWorkflowOwner(context,
                                                                                  command as CreateWorkflowOwnerCommand);

                    return createFunc.BeginInvoke(ar =>
                        {
                            Exception ex = createFunc.EndInvoke(ar);
                            callback(new InstanceStoreAsyncResult(ar, ex));
                        }, state);

                case "LoadWorkflowCommand":
                    Func<Exception> loadFunc = () => ProcessLoadWorkflow(context,
                                                                         command as LoadWorkflowCommand);

                    return loadFunc.BeginInvoke(ar =>
                        {
                            Exception ex = loadFunc.EndInvoke(ar);
                            callback(new InstanceStoreAsyncResult(ar, ex));
                        }, state);

                case "LoadWorkflowByInstanceKeyCommand":
                    Func<Exception> loadByKeyFunc = () => ProcessLoadWorkflowByInstanceKey(context,
                                                                                           command as LoadWorkflowByInstanceKeyCommand);

                    return loadByKeyFunc.BeginInvoke(ar =>
                        {
                            Exception ex = loadByKeyFunc.EndInvoke(ar);
                            callback(new InstanceStoreAsyncResult(ar, ex));
                        }, state);

                case "SaveWorkflowCommand":
                    Func<Exception> saveFunc = () => ProcessSaveWorkflow(context,
                                                                         command as SaveWorkflowCommand);

                    return saveFunc.BeginInvoke(ar =>
                        {
                            Exception ex = saveFunc.EndInvoke(ar);
                            callback(new InstanceStoreAsyncResult(ar, ex));
                        }, state);

                default:
                    return base.BeginTryCommand(
                        context, command, timeout, callback, state);
            }


        }
 protected SqlWorkflowInstanceStoreAsyncResult(System.Runtime.DurableInstancing.InstancePersistenceContext context, System.Runtime.DurableInstancing.InstancePersistenceCommand command, SqlWorkflowInstanceStore store, SqlWorkflowInstanceStoreLock storeLock, Transaction currentTransaction, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state)
 {
     this.DependentTransaction       = (currentTransaction != null) ? currentTransaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete) : null;
     this.InstancePersistenceContext = context;
     this.InstancePersistenceCommand = command;
     this.Store         = store;
     this.StoreLock     = storeLock;
     this.TimeoutHelper = new System.Runtime.TimeoutHelper(timeout);
     base.OnCompleting  = (Action <AsyncResult, Exception>)Delegate.Combine(base.OnCompleting, finallyCallback);
 }
        public LoadRetryAsyncResult(SqlWorkflowInstanceStore store, InstancePersistenceContext context,
            InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state)
            : base(callback, state)
        {
            this.InstanceStore = store;
            this.InstancePersistenceContext = context;
            this.InstancePersistenceCommand = command;
            this.commandTimeout = new TimeoutHelper(timeout);

            InstanceStore.BeginTryCommandInternal(this.InstancePersistenceContext, this.InstancePersistenceCommand,
                this.commandTimeout.RemainingTime(), LoadRetryAsyncResult.onTryCommandCallback, this);
        }
 public ExtendLockAsyncResult
     (
     InstancePersistenceContext context,
     InstancePersistenceCommand command,
     SqlWorkflowInstanceStore store,
     SqlWorkflowInstanceStoreLock storeLock,
     Transaction currentTransaction,
     TimeSpan timeout, 
     AsyncCallback callback, 
     object state
     ) :
     base(context, command, store, storeLock, currentTransaction, timeout, int.MaxValue, callback, state)
 {
 }
 protected SqlWorkflowInstanceStoreAsyncResult
     (
     InstancePersistenceContext context,
     InstancePersistenceCommand command,
     SqlWorkflowInstanceStore store,
     SqlWorkflowInstanceStoreLock storeLock,
     Transaction currentTransaction,
     TimeSpan timeout,
     AsyncCallback callback,
     object state
     ) 
     : this(context, command, store, storeLock, currentTransaction, timeout, store.MaxConnectionRetries, callback, state)
 {
 }
 public DetectActivatableWorkflowsAsyncResult
     (
     InstancePersistenceContext context,
     InstancePersistenceCommand command,
     SqlWorkflowInstanceStore store,
     SqlWorkflowInstanceStoreLock storeLock,
     Transaction currentTransaction,
     TimeSpan timeout,
     AsyncCallback callback,
     object state
     ) :
     base(context, command, store, storeLock, currentTransaction, timeout, callback, state)
 {
 }
 public TestDatabaseVersionAndRunAsyncResult(
     InstancePersistenceContext context,
     InstancePersistenceCommand command,
     SqlWorkflowInstanceStore store,
     SqlWorkflowInstanceStoreLock storeLock,
     Transaction currentTransaction,
     TimeSpan timeout,
     Version targetVersion,
     AsyncCallback callback,
     object state) :
     base(context, command, store, storeLock, currentTransaction, timeout, callback, state)
 {
     this.currentTransaction = currentTransaction;
     this.targetVersion = targetVersion;
 }
예제 #17
0
        private bool SaveWorkflow(InstancePersistenceContext context, SaveWorkflowCommand command)
        {
            if (context.InstanceVersion == -1)
            {
                context.BindAcquiredLock(0);
            }

            if (command.CompleteInstance)
            {
                context.CompletedInstance();
            }
            else
            {
                string instanceType = "";

                const string InstanceTypeXName = "{urn:schemas-microsoft-com:System.Runtime.DurableInstancing/4.0/metadata}InstanceType";
                InstanceValue instanceTypeInstanceValue;
                if (command.InstanceMetadataChanges.TryGetValue(InstanceTypeXName, out instanceTypeInstanceValue))
                {
                    instanceType = instanceTypeInstanceValue.Value.ToString();
                }

                Dictionary<string, object> fullInstanceData = new Dictionary<string, object>();
                fullInstanceData.Add("instanceId", context.InstanceView.InstanceId);
                fullInstanceData.Add("instanceOwnerId", context.InstanceView.InstanceOwner.InstanceOwnerId);
                fullInstanceData.Add("instanceData", SerializeablePropertyBag(command.InstanceData));
                fullInstanceData.Add("instanceMetadata", SerializeInstanceMetadata(context, command));

                foreach (KeyValuePair<XName, InstanceValue> property in command.InstanceMetadataChanges)
                {
                    context.WroteInstanceMetadataValue(property.Key, property.Value);
                }

                context.PersistedInstance(command.InstanceData);

                _stores.Save(WorkflowStoreComponents.Definition
                                                | WorkflowStoreComponents.Metadata
                                                | WorkflowStoreComponents.Streams
                                                | WorkflowStoreComponents.TerminatingError
                                                | WorkflowStoreComponents.Timer
                                                | WorkflowStoreComponents.ActivityState 
                                                | WorkflowStoreComponents.JobState,
                                                fullInstanceData);

            }

            return true;
        }
 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 LoadWorkflowAsyncResult
     (
     InstancePersistenceContext context, 
     InstancePersistenceCommand command, 
     SqlWorkflowInstanceStore store,
     SqlWorkflowInstanceStoreLock storeLock,
     Transaction currentTransaction,
     TimeSpan timeout, 
     AsyncCallback callback, 
     object state
     ) :
     base(context, command, store, storeLock, currentTransaction, timeout, callback, state)
 {
     this.associatedInstanceKeys = new Dictionary<Guid, IDictionary<XName, InstanceValue>>();
     this.completedInstanceKeys = new Dictionary<Guid, IDictionary<XName, InstanceValue>>();
     this.objectSerializer = ObjectSerializerFactory.GetDefaultObjectSerializer();
 }
예제 #20
0
        internal InstancePersistenceContext AcquireExecutionContext(Transaction hostTransaction, TimeSpan timeout)
        {
            bool setOperationPending          = false;
            InstancePersistenceContext result = null;

            try
            {
                result = AcquireContextAsyncResult.End(new AcquireContextAsyncResult(this, hostTransaction, timeout, out setOperationPending));
                Fx.AssertAndThrow(result != null, "Null result returned from AcquireContextAsyncResult (synchronous).");
                return(result);
            }
            finally
            {
                if (result == null && setOperationPending)
                {
                    FinishOperation();
                }
            }
        }
 protected internal override IAsyncResult BeginTryCommand(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state)
 {
     if (context == null)
     {
         throw FxTrace.Exception.ArgumentNull("context");
     }
     if (command == null)
     {
         throw FxTrace.Exception.ArgumentNull("command");
     }
     if (!this.storeLock.IsValid && !(command is CreateWorkflowOwnerCommand))
     {
         throw FxTrace.Exception.AsError(new InstanceOwnerException(command.Name, this.storeLock.LockOwnerId));
     }
     if (this.IsRetryCommand(command))
     {
         return new LoadRetryAsyncResult(this, context, command, timeout, callback, state);
     }
     return this.BeginTryCommandInternal(context, command, timeout, callback, state);
 }
예제 #22
0
            bool DoAfterTransaction()
            {
                AcquireContextAsyncResult setWaitTo = null;

                try
                {
                    lock (this.handle.ThisLock)
                    {
                        if (!this.handle.IsValid)
                        {
                            throw Fx.Exception.AsError(new OperationCanceledException(SRCore.HandleFreed));
                        }

                        if (HostTransaction == null)
                        {
                            this.executionContext = new InstancePersistenceContext(this.handle, this.timeoutHelper.RemainingTime());
                        }
                        else
                        {
                            this.executionContext = new InstancePersistenceContext(this.handle, HostTransaction);
                        }

                        this.handle.AcquirePending          = null;
                        this.handle.CurrentExecutionContext = this.executionContext;
                        this.handle.TooLateToEnlist         = false;
                    }

                    if (HostTransaction != null)
                    {
                        WaitForHostTransaction = new AsyncWaitHandle(EventResetMode.ManualReset);
                        HostTransaction.EnlistVolatile(this, EnlistmentOptions.None);
                        setWaitTo = this;
                    }
                }
                finally
                {
                    this.handle.CurrentTransactionalAsyncResult = setWaitTo;
                }

                return(true);
            }
 // ExtendLockAsyncResult and RecoverInstanceLocksAsyncResult directly call this ctor
 protected SqlWorkflowInstanceStoreAsyncResult
     (
     InstancePersistenceContext context,
     InstancePersistenceCommand command,
     SqlWorkflowInstanceStore store,
     SqlWorkflowInstanceStoreLock storeLock,
     Transaction currentTransaction,
     TimeSpan timeout,
     int maximumRetries,
     AsyncCallback callback,
     object state
     ) :
     base(callback, state)
 {
     this.DependentTransaction = (currentTransaction != null) ? currentTransaction.DependentClone(DependentCloneOption.BlockCommitUntilComplete) : null;
     this.InstancePersistenceContext = context;
     this.InstancePersistenceCommand = command;
     this.Store = store;
     this.StoreLock = storeLock;
     this.TimeoutHelper = new TimeoutHelper(timeout);
     this.OnCompleting += SqlWorkflowInstanceStoreAsyncResult.finallyCallback;
     this.maximumRetries = maximumRetries;
 }
예제 #24
0
            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);
                }
            }
예제 #25
0
		protected internal virtual bool TryCommand (InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout)
		{
			throw new NotImplementedException ();
		}
예제 #26
0
        public void Free()
        {
            if (!this.providerObjectSet)
            {
                throw Fx.Exception.AsError(new InvalidOperationException(SRCore.HandleFreedBeforeInitialized));
            }

            if (!IsValid)
            {
                return;
            }

            List <InstanceHandleReference> handlesPendingResolution = null;
            WaitForEventsAsyncResult       resultToCancel           = null;

            try
            {
                bool needNotification = false;
                InstancePersistenceContext currentContext = null;

                lock (ThisLock)
                {
                    if (!IsValid)
                    {
                        return;
                    }
                    IsValid = false;

                    IEnumerable <XName> eventsToUnbind = null;
                    if (this.pendingOwnerEvents != null && this.pendingOwnerEvents.Count > 0)
                    {
                        eventsToUnbind = this.pendingOwnerEvents.Select(persistenceEvent => persistenceEvent.Name);
                    }
                    if (this.boundOwnerEvents != null && this.boundOwnerEvents.Count > 0)
                    {
                        eventsToUnbind = eventsToUnbind == null ? this.boundOwnerEvents : eventsToUnbind.Concat(this.boundOwnerEvents);
                    }
                    if (eventsToUnbind != null)
                    {
                        Fx.Assert(Owner != null, "How do we have owner events without an owner.");
                        Store.RemoveHandleFromEvents(this, eventsToUnbind, Owner);
                    }
                    if (this.waitResult != null)
                    {
                        resultToCancel  = this.waitResult;
                        this.waitResult = null;
                    }

                    if (OperationPending)
                    {
                        if (AcquirePending != null)
                        {
                            // If in this stage, we need to short-circuit the pending transaction.
                            Fx.Assert(CurrentTransactionalAsyncResult != null, "Should have a pending transaction if we are waiting for it.");
                            CurrentTransactionalAsyncResult.WaitForHostTransaction.Set();
                            this.needFreedNotification = true;
                        }
                        else
                        {
                            // Here, just notify the currently executing command.
                            Fx.Assert(CurrentExecutionContext != null, "Must have either this or AcquirePending set.");
                            currentContext = CurrentExecutionContext;
                        }
                    }
                    else
                    {
                        needNotification = true;

                        if (this.inProgressBind != null)
                        {
                            Owner.CancelBind(ref this.inProgressBind, ref handlesPendingResolution);
                        }
                        else if (Version != -1)
                        {
                            // This means the handle was successfully bound in the past.  Need to remove it from the table of handles.
                            Owner.Unbind(this);
                        }
                    }
                }

                if (currentContext != null)
                {
                    // Need to do this not in a lock.
                    currentContext.NotifyHandleFree();

                    lock (ThisLock)
                    {
                        if (OperationPending)
                        {
                            this.needFreedNotification = true;

                            // Cancel any pending lock reclaim here.
                            if (this.inProgressBind != null)
                            {
                                Fx.Assert(Owner != null, "Must be bound to owner to have an inProgressBind for the lock in CancelReclaim.");

                                // Null reason defaults to OperationCanceledException.  (Defer creating it since this might not be a
                                // reclaim attempt, but we don't know until we take the HandlesLock.)
                                Owner.FaultBind(ref this.inProgressBind, ref handlesPendingResolution, null);
                            }
                        }
                        else
                        {
                            needNotification = true;
                        }
                    }
                }

                if (needNotification)
                {
                    Store.FreeInstanceHandle(this, ProviderObject);
                }
            }
            finally
            {
                if (resultToCancel != null)
                {
                    resultToCancel.Canceled();
                }

                InstanceOwner.ResolveHandles(handlesPendingResolution);
            }
        }
예제 #27
0
		protected internal virtual IAsyncResult BeginTryCommand (InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state)
		{
			if (try_command_delegate == null)
				try_command_delegate = new Func<InstancePersistenceContext, InstancePersistenceCommand, TimeSpan, bool> (TryCommand);
			return try_command_delegate.BeginInvoke (context, command, timeout, callback, state);
		}
            public ExecuteAsyncResult(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout)
                : this(command, timeout, null, null)
            {
                this.context = context;

                this.priorAsyncResult = this.context.LastAsyncResult;
                Fx.Assert(this.priorAsyncResult != null, "The LastAsyncResult should already have been checked.");
                this.priorAsyncResult.executeCalledByCurrentCommand = true;

                bool success = false;
                try
                {
                    this.context.LastAsyncResult = this;
                    RunLoopCore(true);
                    success = true;
                }
                finally
                {
                    this.context.LastAsyncResult = this.priorAsyncResult;
                    if (!success && this.context.IsHandleDoomedByRollback)
                    {
                        this.context.InstanceHandle.Free();
                    }
                }
                Complete(true);
            }
            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);
            }
예제 #30
0
 private bool DeleteWorkflowOwner(InstancePersistenceContext context, DeleteWorkflowOwnerCommand command)
 {
     return true;
 }
예제 #31
0
 public void Free()
 {
     if (!this.providerObjectSet)
     {
         throw Fx.Exception.AsError(new InvalidOperationException(SRCore.HandleFreedBeforeInitialized));
     }
     if (this.IsValid)
     {
         List <InstanceHandleReference> handlesPendingResolution = null;
         WaitForEventsAsyncResult       waitResult = null;
         try
         {
             bool flag = false;
             InstancePersistenceContext currentExecutionContext = null;
             lock (this.ThisLock)
             {
                 if (!this.IsValid)
                 {
                     return;
                 }
                 this.IsValid = false;
                 IEnumerable <XName> first = null;
                 if ((this.pendingOwnerEvents != null) && (this.pendingOwnerEvents.Count > 0))
                 {
                     first = from persistenceEvent in this.pendingOwnerEvents select persistenceEvent.Name;
                 }
                 if ((this.boundOwnerEvents != null) && (this.boundOwnerEvents.Count > 0))
                 {
                     first = (first == null) ? this.boundOwnerEvents : first.Concat <XName>(this.boundOwnerEvents);
                 }
                 if (first != null)
                 {
                     this.Store.RemoveHandleFromEvents(this, first, this.Owner);
                 }
                 if (this.waitResult != null)
                 {
                     waitResult      = this.waitResult;
                     this.waitResult = null;
                 }
                 if (this.OperationPending)
                 {
                     if (this.AcquirePending != null)
                     {
                         this.CurrentTransactionalAsyncResult.WaitForHostTransaction.Set();
                         this.needFreedNotification = true;
                     }
                     else
                     {
                         currentExecutionContext = this.CurrentExecutionContext;
                     }
                 }
                 else
                 {
                     flag = true;
                     if (this.inProgressBind != null)
                     {
                         this.Owner.CancelBind(ref this.inProgressBind, ref handlesPendingResolution);
                     }
                     else if (this.Version != -1L)
                     {
                         this.Owner.Unbind(this);
                     }
                 }
             }
             if (currentExecutionContext != null)
             {
                 currentExecutionContext.NotifyHandleFree();
                 lock (this.ThisLock)
                 {
                     if (this.OperationPending)
                     {
                         this.needFreedNotification = true;
                         if (this.inProgressBind != null)
                         {
                             this.Owner.FaultBind(ref this.inProgressBind, ref handlesPendingResolution, null);
                         }
                     }
                     else
                     {
                         flag = true;
                     }
                 }
             }
             if (flag)
             {
                 this.Store.FreeInstanceHandle(this, this.ProviderObject);
             }
         }
         finally
         {
             if (waitResult != null)
             {
                 waitResult.Canceled();
             }
             InstanceOwner.ResolveHandles(handlesPendingResolution);
         }
     }
 }
예제 #32
0
        private bool LoadWorkflow(InstancePersistenceContext context, LoadWorkflowCommand command)
        {
            if (command.AcceptUninitializedInstance)
            {
                return false;
            }

            if (context.InstanceVersion == -1)
            {
                context.BindAcquiredLock(0);
            }

            Guid instanceId = context.InstanceView.InstanceId;
            Guid instanceOwnerId = context.InstanceView.InstanceOwner.InstanceOwnerId;

            IDictionary<XName, InstanceValue> instanceData = null;
            IDictionary<XName, InstanceValue> instanceMetadata = null;

            Dictionary<string, object> fullInstanceData = _stores.LoadWorkflowContext();
            
            instanceData = this.DeserializePropertyBag((Dictionary<XName, object>)fullInstanceData["instanceData"]);
            instanceMetadata = this.DeserializePropertyBag((Dictionary<XName, object>)fullInstanceData["instanceMetadata"]);

            context.LoadedInstance(InstanceState.Initialized, instanceData, instanceMetadata, null, null);

            return true;
        }
예제 #33
0
 private bool CreateWorkflowOwner(InstancePersistenceContext context, CreateWorkflowOwnerCommand command)
 {
     Guid instanceOwnerId = Guid.NewGuid();
     context.BindInstanceOwner(instanceOwnerId, instanceOwnerId);
     context.BindEvent(HasRunnableWorkflowEvent.Value);
     return true;
 }
예제 #34
0
            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 BindReclaimedLockAsyncResult(InstancePersistenceContext context, AsyncWaitHandle wait, TimeSpan timeout, AsyncCallback callback, object state)
                : base(callback, state)
            {
                this.context = context;

                if (wait.WaitAsync(BindReclaimedLockAsyncResult.waitComplete, this, timeout))
                {
                    this.context.ConcludeBindReclaimedLockHelper();
                    Complete(true);
                }
            }
            public ExecuteAsyncResult(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state)
                : this(command, timeout, callback, state)
            {
                this.context = context;

                this.priorAsyncResult = this.context.LastAsyncResult;
                Fx.Assert(this.priorAsyncResult != null, "The LastAsyncResult should already have been checked.");
                this.priorAsyncResult.executeCalledByCurrentCommand = true;

                OnCompleting = new Action<AsyncResult, Exception>(SimpleCleanup);

                bool completeSelf = false;
                bool success = false;
                try
                {
                    this.context.LastAsyncResult = this;
                    if (RunLoop())
                    {
                        completeSelf = true;
                    }
                    success = true;
                }
                finally
                {
                    if (!success)
                    {
                        this.context.LastAsyncResult = this.priorAsyncResult;
                    }
                }
                if (completeSelf)
                {
                    Complete(true);
                }
            }
예제 #37
0
 protected internal virtual bool TryCommand(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout)
 {
     throw new NotImplementedException();
 }
예제 #38
0
        private Dictionary<XName, object> SerializeInstanceMetadata(InstancePersistenceContext context, SaveWorkflowCommand command)
        {
            Dictionary<XName, object> metadata = null;

            foreach (var property in command.InstanceMetadataChanges)
            {
                if (!property.Value.Options.HasFlag(InstanceValueOptions.WriteOnly))
                {
                    if (metadata == null)
                    {
                        metadata = new Dictionary<XName, object>();
                        // copy current metadata. note that we must rid of InstanceValue as it is not properly serializeable
                        foreach (var m in context.InstanceView.InstanceMetadata)
                        {
                            metadata.Add(m.Key, m.Value.Value);
                        }
                    }

                    if (metadata.ContainsKey(property.Key))
                    {
                        if (property.Value.IsDeletedValue) metadata.Remove(property.Key);
                        else metadata[property.Key] = property.Value.Value;
                    }
                    else
                    {
                        if (!property.Value.IsDeletedValue) metadata.Add(property.Key, property.Value.Value);
                    }
                }
            }

            if (metadata == null)
                metadata = new Dictionary<XName, object>();

            return metadata;
        }
예제 #39
0
 protected internal virtual bool TryCommand(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout)
 {
     return(EndTryCommand(BeginTryCommand(context, command, timeout, null, null)));
 }
 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);
     }
 }
예제 #41
0
            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);
                }
            }
예제 #42
0
 protected internal virtual IAsyncResult BeginTryCommand(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state)
 {
     return(new CompletedAsyncResult <bool>(false, callback, state));
 }
 private bool DoAfterTransaction()
 {
     InstanceHandle.AcquireContextAsyncResult result = null;
     try
     {
         lock (this.handle.ThisLock)
         {
             if (!this.handle.IsValid)
             {
                 throw Fx.Exception.AsError(new OperationCanceledException(SRCore.HandleFreed));
             }
             if (this.HostTransaction == null)
             {
                 this.executionContext = new InstancePersistenceContext(this.handle, this.timeoutHelper.RemainingTime());
             }
             else
             {
                 this.executionContext = new InstancePersistenceContext(this.handle, this.HostTransaction);
             }
             this.handle.AcquirePending = null;
             this.handle.CurrentExecutionContext = this.executionContext;
             this.handle.TooLateToEnlist = false;
         }
         if (this.HostTransaction != null)
         {
             this.WaitForHostTransaction = new AsyncWaitHandle(EventResetMode.ManualReset);
             this.HostTransaction.EnlistVolatile(this, EnlistmentOptions.None);
             result = this;
         }
     }
     finally
     {
         this.handle.CurrentTransactionalAsyncResult = result;
     }
     return true;
 }
예제 #44
0
 public InstanceView EndExecute(IAsyncResult result)
 {
     return(InstancePersistenceContext.EndOuterExecute(result));
 }