예제 #1
0
        static ValkQueueWFMessage GetNextStep(ValkQueueWFMessage WFMessage)
        {
            ValkQueueWFMessage ReplyMessage = new ValkQueueWFMessage();

            ReplyMessage.Command = ValkQueueWFMessage.WFCommand.WFC_WAIT;
            bool stepfound = false;
            int  i         = 0;

            //cycle through all of our current steps until we find an active one
            //todo: provide an actual queue of active steps so we don't have to go searching
            //      we should be adding to "active" as they come in, and moving to a list for "pending"
            //      once processing starts
            while (stepfound == false && i < ActiveSteps.Count)
            {
                if (ActiveSteps[i].Status == "active")
                {
                    ActiveSteps[i].Status    = "pending";
                    ReplyMessage.Step        = ActiveSteps[i].DeepClone();
                    ReplyMessage.InstanceKey = ReplyMessage.Step.InstanceKey;
                    ReplyMessage.Command     = ValkQueueWFMessage.WFCommand.WFC_LOAD;
                    stepfound = true;
                }
                i++;
            }
            return(ReplyMessage);
        }
예제 #2
0
        /// <summary>
        /// Control function for this class so we can gracefully startup/pause/exit the entire system
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="revents"></param>
        static void ValkQueueWFStepsCTRL_PollInHandler(Socket socket, IOMultiPlex revents)
        {
            string Message = socket.Recv(Encoding.Unicode);

            Console.WriteLine(Message);
            if (Message == "GO")
            {
                Stop = false;
            }
            else if (Message == "STOP")
            {
                Stop = true;
            }
            else if (Message == "EXIT")
            {
                ValkQueueWFMessage ExitMessage = new ValkQueueWFMessage();
                ExitMessage.Command = ValkQueueWFMessage.WFCommand.WFC_EXIT;
                QueueDBHandlerComm.Send <ValkQueueWFMessage>(ExitMessage);
                string mesg = QueueDBHandlerComm.Recv(Encoding.Unicode);
                DBHandler.Join();
                Stop = true;
                Exit = true;
            }
            socket.Send("OK:" + Message, Encoding.Unicode);
        }
예제 #3
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--;
                }
            }
        }
예제 #4
0
        static void ValkQueueWFSteps_PollInHandler(Socket socket, IOMultiPlex revents)
        {
            string             reply     = "";
            ValkQueueWFMessage WFMessage = socket.Recv <ValkQueueWFMessage>();

            switch (WFMessage.Command)
            {
            case ValkQueueWFMessage.WFCommand.WFC_WAIT:
                //great, don't do anything, probably a warning
                socket.Send("OK", Encoding.Unicode);
                break;

            case ValkQueueWFMessage.WFCommand.WFC_LOAD:
                //warning, we don't handle this
                socket.Send("OK", Encoding.Unicode);
                break;

            case ValkQueueWFMessage.WFCommand.WFC_CANPROCESS:
                //this will be a big one...
                socket.Send <ValkQueueWFMessage>(GetNextStep(WFMessage));
                break;

            case ValkQueueWFMessage.WFCommand.WFC_ACTIVATE:
                //set first step to active, insert neededness
                WFMessage.Step.Status = "active";
                QueueDBHandlerComm.Send <ValkQueueWFMessage>(WFMessage);
                reply = QueueDBHandlerComm.Recv(Encoding.Unicode);
                socket.Send("OK", Encoding.Unicode);
                ActiveSteps.Add(WFMessage.Step);

                break;

            case ValkQueueWFMessage.WFCommand.WFC_COMPLETE:
                //should also try to pick up the next step here, no reason to waste cycles
                WFMessage.Step.Status = "complete";
                QueueDBHandlerComm.Send <ValkQueueWFMessage>(WFMessage);
                reply = QueueDBHandlerComm.Recv(Encoding.Unicode);
                HandleComplete(WFMessage.Step);
                ValkQueueWFMessage NewMessage = new ValkQueueWFMessage();
                NewMessage.Command = ValkQueueWFMessage.WFCommand.WFC_CANPROCESS;
                socket.Send <ValkQueueWFMessage>(GetNextStep(NewMessage));

                break;

            case ValkQueueWFMessage.WFCommand.WFC_EXCEPTION:
                break;

            case ValkQueueWFMessage.WFCommand.WFC_STOP:
                socket.Send("OK", Encoding.Unicode);
                break;

            case ValkQueueWFMessage.WFCommand.WFC_SUBFLOW:
                socket.Send("OK", Encoding.Unicode);
                break;

            default:
                break;
            }
        }
예제 #5
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);
            }
        }
예제 #6
0
        //public void Initialize()
        //{
        //    Thread Processor;
        //    Processor = new Thread(new ThreadStart(ValkQueueWFSteps.RunQueue));
        //    Processor.Start();
        //}
        public static void RunProcessor()
        {
            if (QueueContext == null)
            {
                QueueContext = new Context(1);
            }
            //throw new System.Exception("QueueContext not set");
            QueueComm = QueueContext.Socket(SocketType.REQ);
            QueueComm.Connect("tcp://127.0.0.1:5000");

            /*
             * ActivatorIntraComm.Bind("tcp://*:5001");
             * ActivatorControllerIntraComm = ActContext.Socket(SocketType.REP);
             * ActivatorControllerIntraComm.Connect("inproc://activatorcontrol");
             * QueueComm = ActContext.Socket(SocketType.REQ);
             * QueueComm.Connect("tcp://127.0.0.1:5000");
             * */
            ValkQueueWFMessage WFMessage = new ValkQueueWFMessage();

            WFMessage.Command = ValkQueueWFMessage.WFCommand.WFC_CANPROCESS;
            while (true)
            {
                try
                {
                    //Thread.Sleep(10000);
                    QueueComm.Send <ValkQueueWFMessage>(WFMessage);
                    WFMessage = QueueComm.Recv <ValkQueueWFMessage>();
                }
                catch (ZMQ.Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                if (WFMessage.Command == ValkQueueWFMessage.WFCommand.WFC_WAIT)
                {
                    Thread.Sleep(5000);
                    WFMessage.Command = ValkQueueWFMessage.WFCommand.WFC_CANPROCESS;
                }
                else
                {
                    if (WFMessage.Command != ValkQueueWFMessage.WFCommand.WFC_CANPROCESS)
                    {
                        ProcessData(ref WFMessage);
                    }
                }
            }
        }
예제 #7
0
 public static void ProcessData(ref ValkQueueWFMessage WFMessage)
 {
     //default, automatically complete everything
     if (StepHandlers.ContainsKey(WFMessage.Step.HandleCategory))
     {
         StepHandlers[WFMessage.Step.HandleCategory].HandleStep(ref WFMessage);
     }
     else
     {
         if (DefaultHandler == null)
         {
             Console.WriteLine("No handler for " + WFMessage.Step.HandleCategory + " and no default provided");
         }
         else
         {
             DefaultHandler.HandleStep(ref WFMessage);
         }
     }
 }
예제 #8
0
        public static void StartPolling(IDatabaseHandler dbHandler)
        {
            if (PollContext == null)
            {
                throw new System.Exception("PollContext not set");
            }
            //  Prepare our sockets
            PollerControlIntraComm = PollContext.Socket(SocketType.REP);
            PollerControlIntraComm.Connect("inproc://pollercontrol");

            ActivatorIntraComm = PollContext.Socket(SocketType.REQ);
            ActivatorIntraComm.Connect("inproc://activator");

            PollItem[] Poller = new PollItem[1];
            Poller[0] = PollerControlIntraComm.CreatePollItem(IOMultiPlex.POLLIN);
            Poller[0].PollInHandler += new PollHandler(PollerCTRL_PollInHandler);
            while (!Exit)
            {
                PollContext.Poll(Poller, 5000);
                if (!Stop)
                {
                    //poll
                    //get all available pending workflow instances

                    DataTable dt = dbHandler.GetPendingWFInstances();
                    foreach (DataRow Row in dt.Rows)
                    {
                        //send to kickoff
                        ValkQueueWFMessage Message = new ValkQueueWFMessage();
                        Message.Command      = ValkQueueWFMessage.WFCommand.WFC_LOAD;
                        Message.InstanceID   = int.Parse(Row["WFInstanceID"].ToString());
                        Message.InstanceKey  = Row["InstanceKey"].ToString();
                        Message.InstanceType = Row["WFType"].ToString();
                        ActivatorIntraComm.Send <ValkQueueWFMessage>(Message);
                        string message = ActivatorIntraComm.Recv(Encoding.Unicode);
                        //Console.WriteLine("Instance Insert Reply Received: " + message);
                    }
                }
            }
        }
예제 #9
0
        static void ValkQueueDBHandler_PollInHandler(Socket socket, IOMultiPlex revents)
        {
            ValkQueueWFMessage WFMessage = socket.Recv <ValkQueueWFMessage>();

            switch (WFMessage.Command)
            {
            case ValkQueueWFMessage.WFCommand.WFC_EXIT:
                socket.Send("OK", Encoding.Unicode);
                Exit = true;
                break;

            case ValkQueueWFMessage.WFCommand.WFC_ACTIVATE:
                StepsToUpdate.Add(WFMessage);
                socket.Send("OK", Encoding.Unicode);
                break;

            case ValkQueueWFMessage.WFCommand.WFC_COMPLETE:
                StepsToUpdate.Add(WFMessage);
                socket.Send("OK", Encoding.Unicode);
                break;

            case ValkQueueWFMessage.WFCommand.WFC_SKIP:
                StepsToUpdate.Add(WFMessage);
                socket.Send("OK", Encoding.Unicode);
                break;

            case ValkQueueWFMessage.WFCommand.WFC_EXCEPTION:
                break;

            case ValkQueueWFMessage.WFCommand.WFC_STOP:
                break;

            case ValkQueueWFMessage.WFCommand.WFC_SUBFLOW:
                break;

            default:
                break;
            }
        }
예제 #10
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--;
            }
        }