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); } } }
/// <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); }
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); } } }
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); }