Beispiel #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);
        }
Beispiel #2
0
        private bool SaveWorkflow(InstancePersistenceContext context, SaveWorkflowCommand command)
        {
            if (context.InstanceVersion == -1)
            {
                context.BindAcquiredLock(0);
            }

            if (command.CompleteInstance)
            {
                context.CompletedInstance();
                if (!KeepInstanceDataAfterCompletion && ToDelete != null)
                {
                    //DeleteFiles(context.InstanceView.InstanceId);
                    ToDelete();
                }
            }
            else
            {
                Dictionary <string, InstanceValue> instanceData     = SerializeablePropertyBagConvertXNameInstanceValue(command.InstanceData);
                Dictionary <string, InstanceValue> instanceMetadata = SerializeInstanceMetadataConvertXNameInstanceValue(context, command);

                try
                {
                    //serialize_dc(instanceData, instanceMetadata);
                    //string serializedCorrelation = WorkflowSerialization.Serialize<WorkflowCorrelation>(this.Correlation);
                    string serializedInstanceData     = WorkflowSerialization.Serialize <Dictionary <string, InstanceValue> >(instanceData);
                    string serializedInstanceMetadata = WorkflowSerialization.Serialize <Dictionary <string, InstanceValue> >(instanceMetadata);

                    if (ToPersist != null)
                    {
                        ToPersist(new Serialized()
                        {
                            SerializedInstanceData     = WorkflowSerialization.Serialize <Dictionary <string, InstanceValue> >(instanceData),
                            SerializedInstanceMetadata = WorkflowSerialization.Serialize <Dictionary <string, InstanceValue> >(instanceMetadata)
                        });
                    }
                }
                catch (Exception exc)
                {
                    throw exc;
                }

                context.PersistedInstance(command.InstanceData);
                if (command.CompleteInstance)
                {
                    context.CompletedInstance();
                }

                if (command.UnlockInstance || command.CompleteInstance)
                {
                    context.InstanceHandle.Free();
                }
            }

            return(true);
        }
        private bool SaveWorkflow(InstancePersistenceContext context, SaveWorkflowCommand command)
        {
            if (context.InstanceVersion == -1)
            {
                context.BindAcquiredLock(0);
            }

            if (command.CompleteInstance)
            {
                context.CompletedInstance();
                if (!KeepInstanceDataAfterCompletion)
                {
                    DeleteFiles(context.InstanceView.InstanceId);
                }
            }
            else
            {
                Dictionary <string, InstanceValue> instanceData     = SerializeablePropertyBagConvertXNameInstanceValue(command.InstanceData);
                Dictionary <string, InstanceValue> instanceMetadata = SerializeInstanceMetadataConvertXNameInstanceValue(context, command);

                try
                {
                    var serializedInstanceData = JsonConvert.SerializeObject(instanceData, Formatting.Indented, _jsonSerializerSettings);
                    File.WriteAllText(_storeDirectoryPath + "\\" + context.InstanceView.InstanceId + "-InstanceData", serializedInstanceData);

                    var serializedInstanceMetadata = JsonConvert.SerializeObject(instanceMetadata, Formatting.Indented, _jsonSerializerSettings);
                    File.WriteAllText(_storeDirectoryPath + "\\" + context.InstanceView.InstanceId + "-InstanceMetadata", serializedInstanceMetadata);
                }
                catch (Exception)
                {
                    throw;
                }

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

                context.PersistedInstance(command.InstanceData);
                if (command.CompleteInstance)
                {
                    context.CompletedInstance();
                }

                if (command.UnlockInstance || command.CompleteInstance)
                {
                    context.InstanceHandle.Free();
                }
            }

            return(true);
        }
Beispiel #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;

            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);
        }
Beispiel #5
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);
        }
Beispiel #6
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);
        }
Beispiel #7
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);
        }
Beispiel #8
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);
        }
Beispiel #9
0
        private bool SaveWorkflow(InstancePersistenceContext context, SaveWorkflowCommand command)
        {
            if (context.InstanceVersion == -1)
            {
                context.BindAcquiredLock(0);
            }

            if (command.CompleteInstance)
            {
                context.CompletedInstance();
                if (!KeepInstanceDataAfterCompletion)
                {
                    _repository.Delete(context.InstanceView.InstanceId);
                }
            }
            else
            {
                var data     = SerializeData(command.InstanceData);
                var metadata = SerializeMetadata(context.InstanceView.InstanceMetadata, command.InstanceMetadataChanges);

                _repository.Save(context.InstanceView.InstanceId, new InstanceDataPackage(metadata, data));


                foreach (var property in command.InstanceMetadataChanges)
                {
                    context.WroteInstanceMetadataValue(property.Key, property.Value);
                }

                context.PersistedInstance(command.InstanceData);
                if (command.CompleteInstance)
                {
                    context.CompletedInstance();
                }

                if (command.UnlockInstance || command.CompleteInstance)
                {
                    context.InstanceHandle.Free();
                }
            }

            return(true);
        }
Beispiel #10
0
        private long ProcessSaveCommand(InstancePersistenceContext context, SaveWorkflowCommand 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);
                }

                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 (instance.State == InstanceState.Completed)
                {
                    throw new InstanceCompleteException(command.Name, context.InstanceView.InstanceId);
                }

                if (instance.Owner == Guid.Empty)
                {
                    if (context.InstanceView.IsBoundToLock)
                    {
                        context.InstanceHandle.Free();
                        throw new InstanceLockLostException(command.Name, context.InstanceView.InstanceId);
                    }

                    instance.Version++;
                    instance.Owner = context.InstanceView.InstanceOwner.InstanceOwnerId;
                    PersistenceItemManager.SaveToFile <Instance>(instance);
                    context.BindAcquiredLock(instance.Version);
                }
                else
                {
                    if (instance.Owner != context.InstanceView.InstanceOwner.InstanceOwnerId)
                    {
                        if (context.InstanceView.IsBoundToLock)
                        {
                            context.InstanceHandle.Free();
                            throw new InstanceLockLostException(command.Name, context.InstanceView.InstanceId);
                        }

                        throw new InstanceLockedException(command.Name, instance.Owner);
                    }
                    if (context.InstanceView.IsBoundToLock)
                    {
                        if (context.InstanceVersion != instance.Version)
                        {
                            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);
                        }
                    }
                    else
                    {
                        // 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);
                    }
                }
            }

            foreach (KeyValuePair <Guid, IDictionary <XName, InstanceValue> > keyEntry in command.InstanceKeysToAssociate)
            {
                Key key = PersistenceItemManager.Load <Key>(keyEntry.Key);
                if (key != null)
                {
                    if (key.TargetInstanceId != Guid.Empty && key.TargetInstanceId != context.InstanceView.InstanceId)
                    {
                        throw new InstanceKeyCollisionException(command.Name, context.InstanceView.InstanceId, new InstanceKey(keyEntry.Key), key.TargetInstanceId);
                    }
                    // The SaveWorkflowCommand treats this as a no-op, whether completed or not.
                }
                else
                {
                    key = new Key()
                    {
                        Id               = keyEntry.Key,
                        State            = InstanceKeyState.Associated,
                        TargetInstanceId = context.InstanceView.InstanceId,
                        Metadata         = new PropertyBag(keyEntry.Value)
                    };
                    PersistenceItemManager.SaveToFile <Key>(key);
                    context.AssociatedInstanceKey(keyEntry.Key);
                    if (keyEntry.Value != null)
                    {
                        foreach (KeyValuePair <XName, InstanceValue> property in keyEntry.Value)
                        {
                            context.WroteInstanceKeyMetadataValue(keyEntry.Key, property.Key, property.Value);
                        }
                    }
                }
            }

            foreach (Guid keyGuid in command.InstanceKeysToComplete)
            {
                Key key = PersistenceItemManager.Load <Key>(keyGuid);
                if (key != null && key.TargetInstanceId == context.InstanceView.InstanceId)
                {
                    if (key.State == InstanceKeyState.Associated) //if (key.State != InstanceKeyState.Completed)
                    {
                        key.State = InstanceKeyState.Completed;
                        PersistenceItemManager.SaveToFile <Key>(key);
                        context.CompletedInstanceKey(keyGuid);
                    }
                }
                else
                {
                    // The SaveWorkflowCommand does not allow this.  (Should it validate against it?)
                    throw new InvalidOperationException("Attempting to complete a key which is not associated.");
                }
            }

            foreach (Guid keyGuid in command.InstanceKeysToFree)
            {
                Key key = PersistenceItemManager.Load <Key>(keyGuid);
                if (key != null && key.TargetInstanceId == context.InstanceView.InstanceId)
                {
                    if (key.State != InstanceKeyState.Completed)
                    {
                        context.CompletedInstanceKey(keyGuid);
                    }
                    key.State            = InstanceKeyState.Unknown;
                    key.TargetInstanceId = Guid.Empty;
                    key.Metadata         = null;
                    PersistenceItemManager.SaveToFile <Key>(key);
                    context.UnassociatedInstanceKey(keyGuid);
                }
                else
                {
                    // The SaveWorkflowCommand does not allow this.  (Should it validate against it?)
                    throw new InvalidOperationException("Attempting to complete a key which is not associated.");
                }
            }

            foreach (KeyValuePair <Guid, IDictionary <XName, InstanceValue> > keyEntry in command.InstanceKeyMetadataChanges)
            {
                Key key = PersistenceItemManager.Load <Key>(keyEntry.Key);
                if (key != null && key.TargetInstanceId == context.InstanceView.InstanceId && key.State == InstanceKeyState.Associated)
                {
                    if (keyEntry.Value != null)
                    {
                        foreach (KeyValuePair <XName, InstanceValue> property in keyEntry.Value)
                        {
                            if (property.Value.IsDeletedValue)
                            {
                                key.Metadata.Remove(property.Key);
                            }
                            else
                            {
                                key.Metadata[property.Key] = new InstanceValue(property.Value);
                            }
                            context.WroteInstanceKeyMetadataValue(keyEntry.Key, property.Key, property.Value);
                        }
                        PersistenceItemManager.SaveToFile <Key>(key);
                    }
                }
                else
                {
                    // The SaveWorkflowCommand does not allow this.  (Should it validate against it?)
                    throw new InvalidOperationException("Attempting to complete a key which is not associated.");
                }
            }

            foreach (KeyValuePair <XName, InstanceValue> property in command.InstanceMetadataChanges)
            {
                if (property.Value.IsDeletedValue)
                {
                    instance.Metadata.Remove(property.Key);
                }
                else
                {
                    instance.Metadata[property.Key] = new InstanceValue(property.Value);
                }

                context.WroteInstanceMetadataValue(property.Key, property.Value);
            }

            if (command.InstanceData.Count > 0)
            {
                instance.Data = new PropertyBag(command.InstanceData);
                context.PersistedInstance(command.InstanceData);
            }

            PersistenceItemManager.SaveToFile <Instance>(instance);

            // The command does the implicit advancement of everything into safe completed states.
            if (command.CompleteInstance)
            {
                if (instance.Data == null)
                {
                    instance.Data = new PropertyBag();
                    PersistenceItemManager.SaveToFile <Instance>(instance);
                    context.PersistedInstance(new Dictionary <XName, InstanceValue>());
                }

                Queue <Guid> keysToComplete = new Queue <Guid>();

                foreach (KeyValuePair <Guid, InstanceKeyView> keyEntry in context.InstanceView.InstanceKeys)
                {
                    if (keyEntry.Value.InstanceKeyState == InstanceKeyState.Associated)
                    {
                        keysToComplete.Enqueue(keyEntry.Key);
                    }
                }

                foreach (Guid keyToComplete in keysToComplete)
                {
                    Key key = PersistenceItemManager.Load <Key>(keyToComplete);
                    key.State = InstanceKeyState.Completed;
                    PersistenceItemManager.SaveToFile <Key>(key);
                    context.CompletedInstanceKey(keyToComplete);
                }

                instance.State = InstanceState.Completed;
                instance.Owner = Guid.Empty;

                PersistenceItemManager.SaveToFile <Instance>(instance);
                context.CompletedInstance();
                context.InstanceHandle.Free();
            }
            if (command.UnlockInstance)
            {
                instance.Owner = Guid.Empty;
                PersistenceItemManager.SaveToFile <Instance>(instance);
                context.InstanceHandle.Free();
            }

            return(0);
        }
Beispiel #11
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);
        }
Beispiel #12
0
        private long ProcessLoadByKeyCommand(InstancePersistenceContext context, LoadWorkflowByInstanceKeyCommand command)
        {
            Owner owner = CheckOwner(context, command.Name);

            Key      key = PersistenceItemManager.Load <Key>(command.LookupInstanceKey);
            Instance instance;

            if (key == null)
            {
                if (context.InstanceView.IsBoundToLock && context.InstanceView.InstanceId != command.AssociateInstanceKeyToInstanceId)
                {
                    // This happens in the bind reclaimed lock case.
                    context.InstanceHandle.Free();
                    throw new InstanceLockLostException(command.Name, context.InstanceView.InstanceId);
                }
                if (command.AssociateInstanceKeyToInstanceId == Guid.Empty)
                {
                    throw new InstanceKeyNotReadyException(command.Name, new InstanceKey(command.LookupInstanceKey));
                }

                key = new Key()
                {
                    Id = command.LookupInstanceKey,
                    TargetInstanceId = command.AssociateInstanceKeyToInstanceId,
                    Metadata         = new PropertyBag()
                };

                instance = PersistenceItemManager.Load <Instance>(command.AssociateInstanceKeyToInstanceId);
                if (instance == null)
                {
                    // Checking instance.Owner is like an InstanceLockQueryResult.
                    context.QueriedInstanceStore(new InstanceLockQueryResult(command.AssociateInstanceKeyToInstanceId, Guid.Empty));

                    if (context.InstanceView.IsBoundToLock)
                    {
                        // This happens in the bind reclaimed lock case.
                        context.InstanceHandle.Free();
                        throw new InstanceLockLostException(command.Name, context.InstanceView.InstanceId);
                    }

                    context.BindInstance(command.AssociateInstanceKeyToInstanceId);

                    if (command.AcceptUninitializedInstance)
                    {
                        instance = new Instance()
                        {
                            Id       = command.AssociateInstanceKeyToInstanceId,
                            Version  = 1,
                            Metadata = new PropertyBag(),
                            Owner    = context.InstanceView.InstanceOwner.InstanceOwnerId
                        };
                        PersistenceItemManager.SaveToFile <Instance>(instance);
                    }
                    else
                    {
                        throw new Exception("Could not create new Instance");
                    }

                    context.BindAcquiredLock(1);
                }
                else
                {
                    // Checking instance.Owner is like an InstanceLockQueryResult.
                    context.QueriedInstanceStore(new InstanceLockQueryResult(command.AssociateInstanceKeyToInstanceId, 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.Data != null)
                    {
                        // LoadByInstanceKeyCommand only allows auto-association to an uninitialized instance.
                        throw new InstanceCollisionException(command.Name, command.AssociateInstanceKeyToInstanceId);
                    }

                    if (!context.InstanceView.IsBoundToLock)
                    {
                        if (instance.Owner == Guid.Empty)
                        {
                            context.BindInstance(command.AssociateInstanceKeyToInstanceId);
                            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 a pretty weird case - maybe it's a retry?
                            context.BindInstance(command.AssociateInstanceKeyToInstanceId);
                            return(instance.Version);
                        }
                        else
                        {
                            throw new InstanceLockedException(command.Name, instance.Owner);
                        }
                    }
                }

                if (command.InstanceKeysToAssociate.TryGetValue(command.LookupInstanceKey, out IDictionary <XName, InstanceValue> lookupKeyMetadata))
                {
                    key.Metadata = new PropertyBag(lookupKeyMetadata);
                }
                else
                {
                    key.Metadata = new PropertyBag();
                }
                key.Id = command.LookupInstanceKey;
                key.TargetInstanceId = command.AssociateInstanceKeyToInstanceId;
                PersistenceItemManager.SaveToFile <Key>(key);
                context.AssociatedInstanceKey(command.LookupInstanceKey);
                if (lookupKeyMetadata != null)
                {
                    foreach (KeyValuePair <XName, InstanceValue> property in lookupKeyMetadata)
                    {
                        context.WroteInstanceKeyMetadataValue(command.LookupInstanceKey, property.Key, property.Value);
                    }
                }
            }
            else
            {
                if (context.InstanceView.IsBoundToLock && (key.State == InstanceKeyState.Completed || key.TargetInstanceId != context.InstanceView.InstanceId))
                {
                    // This happens in the bind reclaimed lock case.
                    context.InstanceHandle.Free();
                    throw new InstanceLockLostException(command.Name, context.InstanceView.InstanceId);
                }
                if (key.State == InstanceKeyState.Completed)
                {
                    throw new InstanceKeyCompleteException(command.Name, new InstanceKey(command.LookupInstanceKey));
                }

                instance = PersistenceItemManager.Load <Instance>(key.TargetInstanceId);

                // Checking instance.Owner is like an InstanceLockQueryResult.
                context.QueriedInstanceStore(new InstanceLockQueryResult(key.TargetInstanceId, 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.Data == null && !command.AcceptUninitializedInstance)
                {
                    throw new InstanceNotReadyException(command.Name, key.TargetInstanceId);
                }

                if (!context.InstanceView.IsBoundToLock)
                {
                    if (instance.Owner == Guid.Empty)
                    {
                        context.BindInstance(key.TargetInstanceId);
                        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.
                        context.BindInstance(key.TargetInstanceId);
                        return(instance.Version);
                    }
                    else
                    {
                        throw new InstanceLockedException(command.Name, instance.Owner);
                    }
                }
            }

            Key       newKey;
            Exception exception = null;

            foreach (KeyValuePair <Guid, IDictionary <XName, InstanceValue> > keyEntry in command.InstanceKeysToAssociate)
            {
                newKey = PersistenceItemManager.Load <Key>(keyEntry.Key);
                if (newKey == null)
                {
                    newKey = new Key()
                    {
                        Id = keyEntry.Key,
                        TargetInstanceId = key.TargetInstanceId,
                        Metadata         = new PropertyBag(keyEntry.Value)
                    };
                    PersistenceItemManager.AddKeyToInstance(key.TargetInstanceId, newKey);

                    context.AssociatedInstanceKey(keyEntry.Key);
                    if (keyEntry.Value != null)
                    {
                        foreach (KeyValuePair <XName, InstanceValue> property in keyEntry.Value)
                        {
                            context.WroteInstanceKeyMetadataValue(keyEntry.Key, property.Key, property.Value);
                        }
                    }
                }
                else
                {
                    if (newKey.TargetInstanceId != key.TargetInstanceId && exception == null)
                    {
                        exception = new InstanceKeyCollisionException(command.Name, key.TargetInstanceId, new InstanceKey(keyEntry.Key), newKey.TargetInstanceId);
                    }
                }
            }
            if (exception != null)
            {
                throw exception;
            }

            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 = 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);
        }
Beispiel #13
0
        private bool SaveWorkflow(InstancePersistenceContext context, SaveWorkflowCommand command)
        {
            if (context.InstanceVersion == -1)
            {
                context.BindAcquiredLock(0);
            }

            if (command.CompleteInstance)
            {
                context.CompletedInstance();
                if (!KeepInstanceDataAfterCompletion)
                {
                    DeleteFiles(context.InstanceView.InstanceId);
                }
            }
            else
            {
                Dictionary <string, InstanceValue> instanceData     = SerializeablePropertyBagConvertXNameInstanceValue(command.InstanceData);
                Dictionary <string, InstanceValue> instanceMetadata = SerializeInstanceMetadataConvertXNameInstanceValue(context, command);

                try
                {
                    //var serializedInstanceData = JsonConvert.SerializeObject(instanceData, Formatting.Indented, _jsonSerializerSettings);
                    ////File.WriteAllText(_storeDirectoryPath + "\\" + context.InstanceView.InstanceId + "-InstanceData", serializedInstanceData);
                    //File.WriteAllText(_storePathInstanceData, serializedInstanceData);
                    //var test_deserializ = JsonConvert.DeserializeObject<Dictionary<string, InstanceValue>>(serializedInstanceData, _jsonSerializerSettings);

                    //var serializedInstanceMetadata = JsonConvert.SerializeObject(instanceMetadata, Formatting.Indented, _jsonSerializerSettings);
                    ////File.WriteAllText(_storeDirectoryPath + "\\" + context.InstanceView.InstanceId + "-InstanceMetadata", serializedInstanceMetadata);
                    //File.WriteAllText(_storePathInstanceMetadata, serializedInstanceMetadata);
                    serialize_dc(instanceData, instanceMetadata);
                }
                catch (Exception exc)
                {
                    System.Runtime.Serialization.DataContractSerializerSettings settings = new System.Runtime.Serialization.DataContractSerializerSettings
                    {
                        PreserveObjectReferences = true,
                        KnownTypes = _knownTypes
                    };

                    string s1 = null;
                    System.Runtime.Serialization.DataContractSerializer serializer = new System.Runtime.Serialization.DataContractSerializer(instanceData.GetType(), settings);
                    using (MemoryStream ms = new MemoryStream())
                    {
                        serializer.WriteObject(ms, instanceData);
                        s1 = System.Text.Encoding.UTF8.GetString(ms.ToArray());
                    }

                    Dictionary <string, InstanceValue> obj = null;
                    System.Runtime.Serialization.DataContractSerializer deserializer = new System.Runtime.Serialization.DataContractSerializer(instanceData.GetType(), settings);
                    using (MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(s1)))
                    {
                        obj = (Dictionary <string, InstanceValue>)deserializer.ReadObject(ms);
                    }


                    throw;
                }

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

                context.PersistedInstance(command.InstanceData);
                if (command.CompleteInstance)
                {
                    context.CompletedInstance();
                }

                if (command.UnlockInstance || command.CompleteInstance)
                {
                    context.InstanceHandle.Free();
                }
            }

            return(true);
        }
Beispiel #14
0
        private bool SaveWorkflow(InstancePersistenceContext context, SaveWorkflowCommand command)
        {
            if (context.InstanceVersion == -1)
            {
                context.BindAcquiredLock(0);
            }

            if (command.CompleteInstance)
            {
                context.CompletedInstance();
                if (!KeepInstanceDataAfterCompletion)
                {
                    DeleteFiles(context.InstanceView.InstanceId);
                }
            }
            else
            {
                Dictionary <string, InstanceValue> instanceData     = SerializeablePropertyBagConvertXNameInstanceValue(command.InstanceData);
                Dictionary <string, InstanceValue> instanceMetadata = SerializeInstanceMetadataConvertXNameInstanceValue(context, command);

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

                DataContractSerializer instanceDataSerializer;
                DataContractSerializer instanceMetadataSerializer;
                GetDataContractSerializers(out instanceDataSerializer, out instanceMetadataSerializer);

                try
                {
                    instanceDataSerializer.WriteObject(instanceDataStream, instanceData);
                    instanceMetadataSerializer.WriteObject(instanceMetadataStream, instanceMetadata);
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    instanceDataStream.Flush();
                    instanceDataStream.Dispose();
                    instanceMetadataStream.Flush();
                    instanceMetadataStream.Dispose();
                }

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

                context.PersistedInstance(command.InstanceData);
                if (command.CompleteInstance)
                {
                    context.CompletedInstance();
                }

                if (command.UnlockInstance || command.CompleteInstance)
                {
                    context.InstanceHandle.Free();
                }
            }

            return(true);
        }