Exemple #1
0
        protected override bool Execute(CodeActivityContext context)
        {
            var  workflowinstanceid = context.WorkflowInstanceId;
            bool success;

            success = DispatcherSemaphore.WaitOne(workflowinstanceid);

            // Current dispatcher assumes singleton implementation
            // Remove all previous commands
            if (success)
            {
                using (DispatchEngineContainer dec = new DispatchEngineContainer())
                {
                    // refactor for multi instance scheduler
                    foreach (var c in dec.DispatcherControls)
                    {
                        dec.DispatcherControls.Remove(c);
                    }

                    dec.SaveChanges();
                }
            }

            //TODO: Add consistency checks
            // fix up schedule & dispatch pool if no irq & dpc found

            return(success);
        }
        protected override void Execute(CodeActivityContext context)
        {
            var startuptime        = context.GetValue(this.startuptimestamp);
            var currentdatetimeutc = DateTime.UtcNow;

            using (DispatchEngineContainer dec = new DispatchEngineContainer())
            {
                // look for shutdown message(s)
                bool toshutdown = dec.DispatcherControls.Any(c =>
                                                             c.Cmd == EngineControl.Shutdown &&
                                                             c.TimeStamp >= startuptime);

                if (toshutdown)
                {
                    // shutdown cmd found, heading to final state
                    context.SetValue(this.transition, EngineControl.Shutdown);
                }
                else if (dec.IrqQueue.Count() > 0)
                {
                    // go sweep expired schedules & dispatches
                    context.SetValue(this.transition, EngineControl.Interrupt);
                }
                else if (dec.DpcQueue.Count() > 0)
                {
                    // go create missing dispatches
                    context.SetValue(this.transition, EngineControl.Deferred);
                }
                else
                {
                    // poll to find dispatches ready to run or exipred schedules
                    context.SetValue(this.transition, EngineControl.Poll);
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Unlike a regular semaphore, this implementation returns immediately if fails to enter
        /// </summary>
        /// <param name="WorkflowInstanceId"></param>
        /// <returns></returns>
        internal static bool WaitOne(Guid WorkflowInstanceId)
        {
            bool success = false;

            Dispatcher d = new Dispatcher()
            {
                RequestOrigin      = Environment.MachineName,
                TimeStamp          = DateTime.Now,
                WorkflowInstanceID = WorkflowInstanceId
            };

            using (DispatchEngineContainer dec = new DispatchEngineContainer())
            {
                using (TransactionScope ts = new TransactionScope())
                {
                    // Current dispatcher assumes singleton implementation
                    if (dec.Dispatchers.Count() <= 0)
                    {
                        dec.Dispatchers.Add(d);
                        dec.SaveChanges();
                        success = true;
                    }

                    ts.Complete();
                }
            }
            return(success);
        }
Exemple #4
0
        protected override void Execute(CodeActivityContext context)
        {
            IEnumerable <DpcHandle> dpchandles;
            DpcHandle currentDPC = new DpcHandle();
            bool      ishighimportancedpc;
            bool      dpclocked          = false;
            DateTime  currentdatetimeutc = DateTime.UtcNow;

            using (DispatchEngineContainer dec = new DispatchEngineContainer())
            {
                ishighimportancedpc = dec.DpcQueue.Any(dpc => dpc.Importance == Importance.High);

                if (ishighimportancedpc)
                {
                    dpchandles = dec.DpcQueue.Where(dpc => dpc.Importance == Importance.High).ToArray();
                }
                else
                {
                    dpchandles = dec.DpcQueue.ToArray();
                }

                foreach (var dpc in dpchandles)
                {
                    dpc.TimeStamp = currentdatetimeutc;

                    try
                    {
                        dec.SaveChanges();
                        dec.Entry(dpc).Reload();
                        currentDPC = dpc;
                        dpclocked  = true;
                    }
                    catch (DbUpdateConcurrencyException ex)
                    {
                        // TODO: log exception & increment counter
                    }

                    if (dpclocked)
                    {
                        break;
                    }
                }
            }

            if (dpclocked)
            {
                if (ishighimportancedpc)
                {
                    Dispatcher.PlanSchedulingPool(currentDPC);
                }
                else
                {
                    Dispatcher.RunDispatch(currentDPC);
                }
            }
        }
Exemple #5
0
        internal static bool Release(Guid WorkflowInstanceId)
        {
            bool success = false;

            using (DispatchEngineContainer dec = new DispatchEngineContainer())
            {
                using (TransactionScope ts = new TransactionScope())
                {
                    Dispatcher d = dec.Dispatchers.Single(l => l.WorkflowInstanceID == WorkflowInstanceId);

                    if (d != null)
                    {
                        dec.Dispatchers.Remove(d);
                        dec.SaveChanges();
                        success = true;
                    }

                    ts.Complete();
                }
            }
            return(success);
        }
        protected override void Execute(CodeActivityContext context)
        {
            IEnumerable <IrqHandle> interrupts;
            IrqHandle currentIRQ         = new IrqHandle();
            bool      isdispatchirq      = false;
            bool      irqlocked          = false;
            DateTime  currentdatetimeutc = DateTime.UtcNow;

            using (DispatchEngineContainer dec = new DispatchEngineContainer())
            {
                isdispatchirq = dec.IrqQueue.Any(i => i.Level == IRQL.Dispatch);

                if (isdispatchirq)
                {
                    interrupts = dec.IrqQueue.Where(irq => irq.Level == IRQL.Dispatch).ToArray();
                }
                else
                {
                    interrupts = dec.IrqQueue.ToArray();
                }

                foreach (var irqhandle in interrupts)
                {
                    irqhandle.TimeStamp = currentdatetimeutc;

                    try
                    {
                        dec.SaveChanges();
                        dec.Entry(irqhandle).Reload();
                        currentIRQ = irqhandle;
                        irqlocked  = true;
                    }
                    catch (DbUpdateConcurrencyException ex)
                    {
                        // TODO: log exception & increment counter
                    }

                    if (irqlocked)
                    {
                        break;
                    }
                }
            }

            if (irqlocked)
            {
                if (isdispatchirq)
                {
                    Dispatch dispatch;
                    bool     isdispatchcallback;
                    bool     isdispatchready;

                    using (DispatchEngineContainer dec = new DispatchEngineContainer())
                    {
                        dispatch = dec.Dispatches.Single(d => d.Id == currentIRQ.DispatchID);

                        isdispatchcallback = DispatchStatus.Callback == dispatch.StatusID;

                        // we should check status pending to prevent completed/failed from running again
                        isdispatchready = currentdatetimeutc > dispatch.StartDateTimeUtc && DispatchStatus.Pending == dispatch.StatusID;
                    }

                    if (isdispatchcallback)
                    {
                        Dispatcher.RelocateCallbackDispatch(currentIRQ);
                    }
                    else if (isdispatchready)
                    {
                        Dispatcher.MarkDispatchReady(currentIRQ);
                    }
                    else
                    {
                        Dispatcher.SweepSchedulingPool(currentIRQ);
                    }
                }
                else
                {
                    Schedule schedule = null;
                    bool     isscheduleadded;

                    using (DispatchEngineContainer dec = new DispatchEngineContainer())
                    {
                        try
                        {
                            schedule = dec.Schedules.Single(s => s.Id == currentIRQ.ScheduleID);
                        }
                        catch
                        {
                            // TODO: log exception & increment counter
                        }

                        isscheduleadded = !dec.SchedulingPool.Any(s => s.ScheduleID == currentIRQ.ScheduleID);
                    }

                    if (schedule != null)
                    {
                        if (isscheduleadded)
                        {
                            Dispatcher.MarkNewSchedule(currentIRQ);
                        }
                        else
                        {
                            Dispatcher.SweepSchedulingPool(currentIRQ);
                        }
                    }
                    else
                    {
                        // bug fix to handle interrupts for schedules that has been deleted
                        using (DispatchEngineContainer dec = new DispatchEngineContainer())
                        {
                            // remove current interrupt
                            dec.IrqQueue.Attach(currentIRQ);
                            dec.IrqQueue.Remove(currentIRQ);
                            dec.SaveChanges();
                        }
                    }
                }
            }
        }
        protected override CallbackResult Execute(CodeActivityContext context)
        {
            Dispatch              dispatch;
            IrqHandle             handle;
            List <CallbackDevice> devices2remove = new List <CallbackDevice>();
            ScheduleContextData   data           = context.GetValue(this.ContextData);
            CallbackResult        result         = new CallbackResult()
            {
                ScheduleID = data.ScheduleID,
                DispatchID = data.DispatchID,
                Success    = false,
            };

            using (DispatchEngineContainer dec = new DispatchEngineContainer())
            {
                try
                {
                    dispatch = dec.Dispatches.Where(d => d.Id == data.DispatchID).Single();
                    dispatch.CallbackInfo = data.CallbackInfo;

                    // Remove any devices not needed for callback
                    if (data.Devices != null)
                    {
                        var deviceids = (from d in data.Devices
                                         select d.Id).ToList();

                        devices2remove = (from cd in dec.CallbackDevices
                                          where cd.DispatchID == data.DispatchID &&
                                          !(from id in deviceids
                                            select id).Contains(cd.DeviceID)
                                          select cd).ToList();
                    }
                    else
                    {
                        devices2remove = (from cd in dec.CallbackDevices
                                          where cd.DispatchID == data.DispatchID
                                          select cd).ToList();
                    }

                    foreach (var callbackdevice in devices2remove)
                    {
                        dec.CallbackDevices.Remove(callbackdevice);
                    }

                    // set dispatch to callback status
                    dispatch.StatusID = DispatchStatus.Callback;

                    // Interrupt engine at dispatch level
                    handle = new IrqHandle()
                    {
                        ScheduleID = dispatch.ScheduleID,
                        DispatchID = dispatch.Id,
                        Level      = IRQL.Dispatch,
                        TimeStamp  = DateTime.Now
                    };

                    dec.IrqQueue.Add(handle);

                    dec.SaveChanges();

                    result.Success = true;
                }
                catch (Exception ex)
                {
                    result.Success  = false;
                    result.ErrorMsg = ex.Message;
                }
            }

            return(result);
        }