Exemplo n.º 1
0
        static void HandleComplete(ValkWFStep Step)
        {
            string reply = "";

            for (int i = 0; i < Step.NextSteps.Count; i++)
            {
                ValkWFStep NextStep = Step.NextSteps[i];
                if (!NextStep.Skip)
                {
                    if (NextStep.SyncCount > 1)
                    {
                        UpdateSyncCounts(NextStep);
                    }
                    else
                    {
                        //no waiting!
                        ValkQueueWFMessage WFMessage = new ValkQueueWFMessage();
                        NextStep.Status       = "active";
                        WFMessage.Command     = ValkQueueWFMessage.WFCommand.WFC_ACTIVATE;
                        WFMessage.Step        = NextStep;
                        WFMessage.InstanceKey = NextStep.InstanceKey;
                        QueueDBHandlerComm.Send <ValkQueueWFMessage>(WFMessage);
                        reply = QueueDBHandlerComm.Recv(Encoding.Unicode);
                        ActiveSteps.Add(NextStep);
                    }
                }
                else
                {
                    //we may need to update wait counts here
                    //update database
                    ValkQueueWFMessage WFMessage = new ValkQueueWFMessage();
                    NextStep.Status       = "skip";
                    WFMessage.Step        = NextStep;
                    WFMessage.InstanceKey = NextStep.InstanceKey;
                    WFMessage.Command     = ValkQueueWFMessage.WFCommand.WFC_SKIP;
                    QueueDBHandlerComm.Send <ValkQueueWFMessage>(WFMessage);
                    reply = QueueDBHandlerComm.Recv(Encoding.Unicode);

                    //TODO: update sync counts of children, recursively, will need to look for new activates as well
                    //probably doesn't need to be recursive because the system will handle it as the children complete
                    //will need to recurse (or re-insert) for children where this is the only parent to set them to skip
                    // use inproc://queueself and create a new message channel to send messages directly back to itself?
                    // --this won't work, because they will wait for (or expect) a reply on the other side, but its one thread
                }
                Step.NextSteps[i] = NextStep;
            }
            //todo remember to remove from active list
            for (int i = 0; i < ActiveSteps.Count; i++)
            {
                if (ActiveSteps[i].WFTemplateID == Step.WFTemplateID &&
                    ActiveSteps[i].WFTemplateStepID == Step.WFTemplateStepID &&
                    ActiveSteps[i].InstanceKey == Step.InstanceKey)
                {
                    ActiveSteps.RemoveAt(i);
                    //step back since the count changed and the next one will be one behind
                    i--;
                }
            }
        }
Exemplo n.º 2
0
        static void ValkWFActivator_PollInHandler(Socket socket, IOMultiPlex revents)
        {
            //handle workflow instantiations
            ValkQueueWFMessage WFMessage = socket.Recv <ValkQueueWFMessage>();

            if (WFMessage.Command == ValkQueueWFMessage.WFCommand.WFC_LOAD)
            {
                ValkWFStep NewInstance = null;
                //Console.WriteLine("Instance Insert Request Received: " + WFMessage.InstanceID + " " + WFMessage.InstanceKey);
                if (!LoadedInstances.Contains(WFMessage.InstanceID))
                {
                    LoadedInstances.Add(WFMessage.InstanceID);
                    SortedDictionary <int, ValkWFStep> ToInsert = new SortedDictionary <int, ValkWFStep>();

                    dbHandler.StartWFInstance(WFMessage.InstanceID);
                    if (LoadedActiveInstanceByType.ContainsKey(WFMessage.InstanceType))
                    {
                        NewInstance
                            = LoadedInstanceTemplates[LoadedActiveInstanceByType[WFMessage.InstanceType]].DeepClone <ValkWFStep>();
                        BuildInsertWFInstance(ToInsert, NewInstance, WFMessage.InstanceKey, true);
                        //Console.WriteLine(DateTime.Now.ToLongTimeString() + ": Created New Instance: " + WFMessage.InstanceKey);
                    }
                    else
                    {
                        //error, no WF of this type found active
                    }

                    if (ToInsert.Count > 0)
                    {
                        InsertWFInstance(ToInsert);
                        ValkQueueWFMessage QueueMessage = new ValkQueueWFMessage();
                        QueueMessage.InstanceID   = WFMessage.InstanceID;
                        QueueMessage.InstanceKey  = WFMessage.InstanceKey;
                        QueueMessage.InstanceType = WFMessage.InstanceType;
                        QueueMessage.Command      = ValkQueueWFMessage.WFCommand.WFC_ACTIVATE;
                        QueueMessage.Step         = NewInstance;
                        QueueComm.Send <ValkQueueWFMessage>(QueueMessage);
                        string reply = QueueComm.Recv(Encoding.Unicode);
                    }
                    socket.Send("OK", Encoding.Unicode);
                }
                else
                {                //else don't do anything, duplicate message
                    socket.Send("WARN-Duplicate Request", Encoding.Unicode);
                }
            }
            else
            {
                //log error message
                socket.Send("ERROR-Wrong Request Type", Encoding.Unicode);
            }
        }
Exemplo n.º 3
0
        private static void LoadChildren(ValkWFStep CurrentStep, IDatabaseHandler dbHandler)
        {
            List <ValkWFStep> Children = dbHandler.LoadChildSteps(CurrentStep);

            //do children loading outside, here
            for (int i = 0; i < Children.Count(); i++)
            {
                ValkWFStep substep = Children[i];
                LoadChildren(substep, dbHandler);
                Children[i] = substep;
            }
            CurrentStep.NextSteps = Children;
        }
Exemplo n.º 4
0
        private static void LoadWorkflowTemplates(IDatabaseHandler dbHandler)
        {
            //WorkFlowTemplates
            //list to store loads to help reduce recursive SQL queries
            WFTemplateLoadingData loadingData = dbHandler.LoadWFTemplates();

            LoadedActiveInstanceByType = loadingData.LoadedActiveInstanceByType;
            for (int i = 0; i < loadingData.WFsToLoad.Count(); i++)
            {
                ValkWFStep CurrentStep = loadingData.WFsToLoad[i];
                LoadChildren(CurrentStep, dbHandler);
                loadingData.WFsToLoad[i] = CurrentStep;
                LoadedInstanceTemplates[loadingData.WFsToLoad[i].WFTemplateID] = loadingData.WFsToLoad[i];
            }
            Console.WriteLine("Workflows Loaded");
        }
Exemplo n.º 5
0
        /// <summary>
        /// utility function to determine if this step currently has any sync counts
        /// </summary>
        /// <param name="Step"></param>
        /// <returns></returns>
        static bool SyncWaitExists(ValkWFStep Step)
        {
            bool Exists = false;

            if (StepsWithSyncWait.ContainsKey(Step.WFTemplateID))
            {
                if (StepsWithSyncWait[Step.WFTemplateID].ContainsKey(Step.WFTemplateStepID))
                {
                    if (StepsWithSyncWait[Step.WFTemplateID][Step.WFTemplateStepID].ContainsKey(Step.InstanceKey))
                    {
                        Exists = true;
                    }
                }
            }
            return(Exists);
        }
Exemplo n.º 6
0
 /// <summary>
 /// Creates all child-steps of a workflow instance (recursively) so that the entire flow can be inserted
 /// prior to being set active.
 /// </summary>
 /// <param name="ToInsert"></param>
 /// <param name="Step"></param>
 /// <param name="InstanceID"></param>
 /// <param name="insert"></param>
 static void BuildInsertWFInstance(SortedDictionary <int, ValkWFStep> ToInsert, ValkWFStep Step, string InstanceID, bool insert)
 {
     Step.InstanceKey = InstanceID;
     if (insert && !ToInsert.ContainsKey(Step.WFTemplateStepID))
     {
         ToInsert[Step.WFTemplateStepID] = Step;
     }
     else
     {
         insert = false;
     }
     for (int i = 0; i < Step.NextSteps.Count; i++)
     {
         ValkWFStep substep = Step.NextSteps[i];
         BuildInsertWFInstance(ToInsert, substep, InstanceID, insert);
         Step.NextSteps[i] = substep;
     }
 }
Exemplo n.º 7
0
 /// <summary>
 /// Steps can be programatically skipped (not all paths in a workflow are followed)
 /// This function updates the synccount of any children to include the skipped
 /// step as "complete"
 /// </summary>
 /// <param name="Step">Step being skipped</param>
 static void UpdateSkip(ref ValkWFStep Step)
 {
     for (int i = 0; i < Step.NextSteps.Count; i++)
     {
         ValkWFStep substep = Step.NextSteps[i];
         substep.SyncCount--;
         if (substep.SyncCount == 0)
         {
             substep.Skip = true;
             UpdateSkip(ref substep);
         }
         else
         {
             UpdateSyncCounts(substep);
         }
         Step.NextSteps[i] = substep;
     }
 }
Exemplo n.º 8
0
        static void UpdateSyncCounts(ValkWFStep NextStep)
        {
            string reply = "";

            NextStep.SyncCount--;
            //TODO: update sync count in the DB
            if (SyncWaitExists(NextStep))
            {
                StepsWithSyncWait[NextStep.WFTemplateID][NextStep.WFTemplateStepID][NextStep.InstanceKey].SyncCount--;

                //if we're no longer waiting, set this step to active
                if (StepsWithSyncWait[NextStep.WFTemplateID][NextStep.WFTemplateStepID][NextStep.InstanceKey].SyncCount <= 0)
                {
                    ValkQueueWFMessage WFMessage = new ValkQueueWFMessage();
                    NextStep.Status       = "active";
                    WFMessage.Command     = ValkQueueWFMessage.WFCommand.WFC_ACTIVATE;
                    WFMessage.Step        = NextStep;
                    WFMessage.InstanceKey = NextStep.InstanceKey;
                    QueueDBHandlerComm.Send <ValkQueueWFMessage>(WFMessage);
                    reply = QueueDBHandlerComm.Recv(Encoding.Unicode);
                    ActiveSteps.Add(NextStep);
                }
            }
            else
            {
                if (!StepsWithSyncWait.ContainsKey(NextStep.WFTemplateID))
                {
                    StepsWithSyncWait[NextStep.WFTemplateID] = new SortedDictionary <int, SortedDictionary <string, ValkWFStep> >();
                }
                if (!StepsWithSyncWait[NextStep.WFTemplateID].ContainsKey(NextStep.WFTemplateStepID))
                {
                    StepsWithSyncWait[NextStep.WFTemplateID][NextStep.WFTemplateStepID] = new SortedDictionary <string, ValkWFStep>();
                }
                StepsWithSyncWait[NextStep.WFTemplateID][NextStep.WFTemplateStepID][NextStep.InstanceKey] = NextStep.DeepClone();
                StepsWithSyncWait[NextStep.WFTemplateID][NextStep.WFTemplateStepID][NextStep.InstanceKey].SyncCount--;
            }
        }