예제 #1
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);
        }
 private Exception ProcessLoadWorkflow(
     InstancePersistenceContext context,
     LoadWorkflowCommand command)
 {
     try
     {
         if (command.AcceptUninitializedInstance)
         {
             context.LoadedInstance(InstanceState.Uninitialized,
                                    null, null, null, null);
         }
         else
         {
             SharedLoadWorkflow(context, context.InstanceView.InstanceId);
         }
         return(null);
     }
     catch (InstancePersistenceException exception)
     {
         Console.WriteLine(
             // ReSharper disable LocalizableElement
             "ProcessLoadWorkflow exception: {0}",
             // ReSharper restore LocalizableElement
             exception.Message);
         return(exception);
     }
 }
예제 #3
0
        private bool LoadWorkflow(InstancePersistenceContext context, LoadWorkflowCommand command)
        {
            if (command.AcceptUninitializedInstance)
            {
                return(false);
            }

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

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

            FileStream instanceDataStream;
            FileStream instanceMetadataStream;

            GetFileStreams(context.InstanceView.InstanceId, out instanceDataStream, out instanceMetadataStream, FileMode.Open);

            DataContractSerializer instanceDataSerializer;
            DataContractSerializer instanceMetadataSerializer;

            GetDataContractSerializers(out instanceDataSerializer, out instanceMetadataSerializer);

            Dictionary <string, InstanceValue> serializableInstanceData;
            Dictionary <string, InstanceValue> serializableInstanceMetadata;

            try
            {
                serializableInstanceData     = (Dictionary <string, InstanceValue>)instanceDataSerializer.ReadObject(instanceDataStream);
                serializableInstanceMetadata = (Dictionary <string, InstanceValue>)instanceMetadataSerializer.ReadObject(instanceMetadataStream);
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                instanceDataStream.Dispose();
                instanceMetadataStream.Dispose();
            }

            instanceData     = this.DeserializePropertyBagConvertXNameInstanceValue(serializableInstanceData);
            instanceMetadata = this.DeserializePropertyBagConvertXNameInstanceValue(serializableInstanceMetadata);

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

            return(true);
        }
예제 #4
0
        private bool LoadWorkflow(InstancePersistenceContext context, LoadWorkflowCommand command)
        {
            if (command.AcceptUninitializedInstance)
            {
                return(false);
            }

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

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

            Dictionary <string, InstanceValue> serializableInstanceData     = null;
            Dictionary <string, InstanceValue> serializableInstanceMetadata = null;

            try
            {
                if (ToLoad != null)
                {
                    Serialized serialized = ToLoad();

                    serializableInstanceData     = WorkflowSerialization.DeSerialize <Dictionary <string, InstanceValue> >(serialized.SerializedInstanceData);
                    serializableInstanceMetadata = WorkflowSerialization.DeSerialize <Dictionary <string, InstanceValue> >(serialized.SerializedInstanceMetadata);
                }
            }
            catch (Exception exc)
            {
                throw;
            }

            if (serializableInstanceData != null)
            {
                instanceData = this.DeserializePropertyBagConvertXNameInstanceValue(serializableInstanceData);
            }

            if (serializableInstanceMetadata != null)
            {
                instanceMetadata = this.DeserializePropertyBagConvertXNameInstanceValue(serializableInstanceMetadata);
            }

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

            return(true);
        }
예제 #5
0
        private bool LoadWorkflow(InstancePersistenceContext context, LoadWorkflowCommand command)
        {
            if (command.AcceptUninitializedInstance)
            {
                return(false);
            }

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

            var package  = _repository.Load(context.InstanceView.InstanceId);
            var data     = Deserialize(package.Data);
            var metadata = Deserialize(package.Metadata);

            context.LoadedInstance(InstanceState.Initialized, data, metadata, null, null);
            return(true);
        }
예제 #6
0
        private bool LoadWorkflow(InstancePersistenceContext context, LoadWorkflowCommand command)
        {
            if (command.AcceptUninitializedInstance)
            {
                return(false);
            }

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

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

            Dictionary <string, InstanceValue> serializableInstanceData;
            Dictionary <string, InstanceValue> serializableInstanceMetadata;

            try
            {
                ////var serializedInstanceData = File.ReadAllText(_storeDirectoryPath + "\\" + context.InstanceView.InstanceId + "-InstanceData");
                //var serializedInstanceData = File.ReadAllText(_storePathInstanceData);
                //serializableInstanceData = JsonConvert.DeserializeObject<Dictionary<string, InstanceValue>>(serializedInstanceData, _jsonSerializerSettings);

                ////var serializedInstanceMetadata = File.ReadAllText(_storeDirectoryPath + "\\" + context.InstanceView.InstanceId + "-InstanceMetadata");
                //var serializedInstanceMetadata = File.ReadAllText(_storePathInstanceMetadata);
                //serializableInstanceMetadata = JsonConvert.DeserializeObject<Dictionary<string, InstanceValue>>(serializedInstanceMetadata, _jsonSerializerSettings);

                deserialize_dc(out serializableInstanceData, out serializableInstanceMetadata);
            }
            catch (Exception exc)
            {
                throw;
            }

            instanceData     = this.DeserializePropertyBagConvertXNameInstanceValue(serializableInstanceData);
            instanceMetadata = this.DeserializePropertyBagConvertXNameInstanceValue(serializableInstanceMetadata);

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

            return(true);
        }
예제 #7
0
        /// <summary>
        /// Handles a <see cref="LoadWorkflowCommand"/>.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="command"></param>
        Task <bool> LoadWorkflowCommand(InstancePersistenceContext context, LoadWorkflowCommand command)
        {
            if (state.InstanceId != context.InstanceView.InstanceId)
            {
                throw new InvalidOperationException("Loading InstanceId does not match state InstanceId.");
            }

            if (state.InstanceState != InstanceState.Completed)
            {
                context.LoadedInstance(
                    InstanceState.Initialized,
                    LoadInstanceData(context.InstanceView.InstanceId),
                    LoadInstanceMetadata(context.InstanceView.InstanceId),
                    null,
                    null);

                return(Task.FromResult(true));
            }
            else
            {
                return(Task.FromResult(false));
            }
        }
예제 #8
0
        protected override IAsyncResult BeginTryCommand(InstancePersistenceContext context, InstancePersistenceCommand command, TimeSpan timeout, AsyncCallback callback, object state)
        {
            SaveWorkflowCommand save = command as SaveWorkflowCommand;

            if (save != null)
            {
                lock (FileStore.s_thisLock)
                {
                    ProcessSaveCommand(context, save);
                }
            }

            LoadWorkflowCommand load = command as LoadWorkflowCommand;

            if (load != null)
            {
                lock (FileStore.s_thisLock)
                {
                    ProcessLoadCommand(context, load);
                }
            }

            LoadWorkflowByInstanceKeyCommand loadByKey = command as LoadWorkflowByInstanceKeyCommand;

            if (loadByKey != null)
            {
                lock (FileStore.s_thisLock)
                {
                    ProcessLoadByKeyCommand(context, loadByKey);
                }
            }

            if (save != null || load != null || loadByKey != null)
            {
                return(new CompletedAsyncResult(callback, state));
            }

            if (command is CreateWorkflowOwnerCommand createOwner)
            {
                Guid  ownerId = Guid.NewGuid();
                Owner owner   = new Owner();
                lock (s_thisLock)
                {
                    owner.Id        = ownerId;
                    owner.LockToken = Guid.NewGuid();
                    owner.Metadata  = new PropertyBag(createOwner.InstanceOwnerMetadata);
                    PersistenceItemManager.SaveToFile <Owner>(owner);
                }

                context.BindInstanceOwner(ownerId, owner.LockToken);
                context.BindEvent(HasRunnableWorkflowEvent.Value);
                return(new CompletedAsyncResult(callback, state));
            }

            if (command is DeleteWorkflowOwnerCommand deleteOwner)
            {
                Guid ownerId = context.InstanceView.InstanceOwner.InstanceOwnerId;

                lock (FileStore.s_thisLock)
                {
                    Owner owner = PersistenceItemManager.Load <Owner>(ownerId);
                    if (owner != null && owner.LockToken == context.LockToken)
                    {
                        PersistenceItemManager.Remove <Owner>(ownerId);
                    }
                }

                context.InstanceHandle.Free();
                return(new CompletedAsyncResult(callback, state));
            }

            return(base.BeginTryCommand(context, command, timeout, callback, state));
        }
예제 #9
0
        private long ProcessLoadCommand(InstancePersistenceContext context, LoadWorkflowCommand command)
        {
            Owner owner = CheckOwner(context, command.Name);

            Instance instance = PersistenceItemManager.Load <Instance>(context.InstanceView.InstanceId);

            if (instance == null)
            {
                // Checking instance.Owner is like an InstanceLockQueryResult.
                context.QueriedInstanceStore(new InstanceLockQueryResult(context.InstanceView.InstanceId, Guid.Empty));

                if (context.InstanceView.IsBoundToLock)
                {
                    context.InstanceHandle.Free();
                    throw new InstanceLockLostException(command.Name, context.InstanceView.InstanceId);
                }
                if (!command.AcceptUninitializedInstance)
                {
                    throw new InstanceNotReadyException(command.Name, context.InstanceView.InstanceId);
                }
                instance = new Instance()
                {
                    Version  = 1,
                    Id       = context.InstanceView.InstanceId,
                    Owner    = context.InstanceView.InstanceOwner.InstanceOwnerId,
                    Metadata = new PropertyBag()
                };
                PersistenceItemManager.SaveToFile <Instance>(instance);
                context.BindAcquiredLock(1);
            }
            else
            {
                // Checking instance.Owner is like an InstanceLockQueryResult.
                context.QueriedInstanceStore(new InstanceLockQueryResult(context.InstanceView.InstanceId, instance.Owner));

                if (context.InstanceView.IsBoundToLock)
                {
                    if (instance.Version != context.InstanceVersion || instance.Owner != context.InstanceView.InstanceOwner.InstanceOwnerId)
                    {
                        if (context.InstanceVersion > instance.Version)
                        {
                            throw new InvalidProgramException("This is a bug, the context should never be bound higher than the lock.");
                        }
                        context.InstanceHandle.Free();
                        throw new InstanceLockLostException(command.Name, context.InstanceView.InstanceId);
                    }
                }

                if (instance.State == InstanceState.Completed)
                {
                    throw new InstanceCompleteException(command.Name, context.InstanceView.InstanceId);
                }
                if ((instance.Data == null || instance.Data.Count < 1) && !command.AcceptUninitializedInstance)
                {
                    throw new InstanceNotReadyException(command.Name, context.InstanceView.InstanceId);
                }

                if (!context.InstanceView.IsBoundToLock)
                {
                    if (instance.Owner == Guid.Empty)
                    {
                        instance.Version++;
                        instance.Owner = context.InstanceView.InstanceOwner.InstanceOwnerId;
                        PersistenceItemManager.SaveToFile <Instance>(instance);
                        context.BindAcquiredLock(instance.Version);
                    }
                    else if (instance.Owner == context.InstanceView.InstanceOwner.InstanceOwnerId)
                    {
                        // This is the very interesting parallel-convoy conflicting handle race resolution case.  Two handles
                        // can get bound to the same lock, which is necessary to allow parallel convoy to succeed without preventing
                        // zombied locked instances from being reclaimed.
                        return(instance.Version);
                    }
                    else
                    {
                        throw new InstanceLockedException(command.Name, instance.Owner);
                    }
                }
            }

            Dictionary <Guid, IDictionary <XName, InstanceValue> > associatedKeys = new Dictionary <Guid, IDictionary <XName, InstanceValue> >();
            Dictionary <Guid, IDictionary <XName, InstanceValue> > completedKeys  = new Dictionary <Guid, IDictionary <XName, InstanceValue> >();

            foreach (Guid keyId in instance.RelatedKeys)
            {
                Key key = PersistenceItemManager.Load <Key>(keyId);

                if (key.TargetInstanceId == context.InstanceView.InstanceId)
                {
                    if (key.State == InstanceKeyState.Completed)
                    {
                        completedKeys.Add(key.Id, ExcludeWriteOnlyPropertyBagItems(key.Metadata));
                    }
                    else
                    {
                        associatedKeys.Add(key.Id, ExcludeWriteOnlyPropertyBagItems(key.Metadata));
                    }
                }
            }

            instance.State = instance.Data == null ? InstanceState.Uninitialized : InstanceState.Initialized;

            PersistenceItemManager.SaveToFile <Instance>(instance);
            context.LoadedInstance(instance.State, ExcludeWriteOnlyPropertyBagItems(instance.Data),
                                   ExcludeWriteOnlyPropertyBagItems(instance.Metadata), associatedKeys, completedKeys);

            return(0);
        }