Exemplo n.º 1
0
 public void Started(RFWorkQueueItem i)
 {
     if (Filter(i))
     {
         Update(i.Item, DispatchState.Started, null, null);
     }
 }
Exemplo n.º 2
0
        private void ProcessInstructionThread(RFWorkQueueItem i)
        {
            try
            {
                // To make transaction work we'd have to use a single SQL connection to do all reads and writes

                /* using (var ts = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions
                 * {
                 *  IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted,
                 *  Timeout = TimeSpan.FromSeconds(30)
                 * }))*/
                {
                    Log.Debug(this, "Started thread to process instruction {0}", i.Item as RFProcessInstruction);
                    var sink = new RFBufferingSink(); // create thread-local manager to buffer events and instructions, then send them back in bulk
                    RFProcessingResult result = null;
                    try
                    {
                        result = _context.Engine.Process(i.Item as RFInstruction, _context.GetProcessingContext(i.ProcessingKey, sink, sink, null));
                    }
                    catch (Exception ex)
                    {
                        Log.Exception(this, ex, "Exception Thread processing queue item ", i);
                        result = RFProcessingResult.Error(new string[] { ex.Message }, ex is DbException || ex is TimeoutException);
                    }
                    // send result and all buffered events/instructions to external event manager (since
                    // we can't guarantee delivery order with MSMQ)
                    _eventSink.RaiseEvent(this, new RFProcessingFinishedEvent(i, result, sink.GetItems()), i.ProcessingKey);
                    //ts.Complete();
                }
            }
            catch (Exception ex)
            {
                Log.Exception(this, ex, "Exception Thread processing queue item ", i);
            }
        }
Exemplo n.º 3
0
 public void Finished(RFWorkQueueItem i, RFProcessingResult result)
 {
     if (Filter(i))
     {
         Update(i.Item, GetState(result), null, result);
     }
 }
Exemplo n.º 4
0
 public RFProcessingFinishedEvent(RFWorkQueueItem item, RFProcessingResult result, RFWorkQueueItem[] queueItems)
 {
     Item           = item;
     Timestamp      = DateTime.Now;
     Result         = result;
     WorkQueueItems = queueItems;
 }
Exemplo n.º 5
0
 public void CycleFinished(RFWorkQueueItem i, RFProcessingResult result)
 {
     if (i.ProcessingKey != null && _requests.ContainsKey(i.ProcessingKey) && i.Item is RFProcessInstruction)
     {
         _requests[i.ProcessingKey].CycleFinished((i.Item as RFProcessInstruction).ToString(), result);
     }
 }
 // can start if none of its dependencies are running or about to run
 private bool CanStart(RFWorkQueueItem i)
 {
     if (i.Item is RFGraphProcessInstruction)
     {
         var gpi = i.Item as RFGraphProcessInstruction;
         if (_processDependencies.ContainsKey(gpi.ProcessName))
         {
             var depends = _processDependencies[gpi.ProcessName];
             return(!_inProgress.Select(p => p.Item as RFProcessInstruction).Any(p => p != null && depends.Contains(p.ProcessName)) &&
                    !_readyQueue.Select(p => p.Item as RFProcessInstruction).Any(p => p != null && depends.Contains(p.ProcessName)));
         }
     }
     else if (i.Item is RFProcessInstruction)
     {
         // queue up identical instructions
         var pi = i.Item as RFProcessInstruction;
         var existingForSameProcess = _inProgress.Select(p => p.Item as RFProcessInstruction).Where(p => p != null && p.ProcessName == pi.ProcessName)
                                      .Union(_readyQueue.Select(p => p.Item as RFProcessInstruction).Where(p => p != null && p.ProcessName == pi.ProcessName));
         if (existingForSameProcess.Any())
         {
             if (_exclusiveProcesses.Contains(pi.ProcessName))
             {
                 // cannot run concurrently - queue
                 return(false);
             }
             return(!existingForSameProcess.Any(e => RFEngineProcessorParam.Equals(e.ExtractParam(), pi.ExtractParam()))); // catalog update on same key events will be queued
         }
     }
     return(true);
 }
Exemplo n.º 7
0
 public void Queued(RFWorkQueueItem i, long weight)
 {
     if (Filter(i))
     {
         Update(i.Item, DispatchState.Queued, weight, null);
     }
 }
Exemplo n.º 8
0
 public void CycleStarted(RFWorkQueueItem i, int cyclesRemaining)
 {
     if (i.ProcessingKey != null && _requests.ContainsKey(i.ProcessingKey) && i.Item is RFProcessInstruction)
     {
         _requests[i.ProcessingKey].CyclesRemaining(cyclesRemaining);
         _requests[i.ProcessingKey].CycleStarted((i.Item as RFProcessInstruction).ToString());
     }
 }
 private void ProcessingStarted(RFWorkQueueItem item)
 {
     if (item.Item is RFProcessInstruction)
     {
         _inProgress.Add(item);
         RFStatic.Log.Debug(typeof(RFGraphDispatchQueue), "Processing started for {0} ({1} in progress)", item.Item, _inProgress.Count);
         _dispatchStore.Started(item);
     }
     RefreshReadyQueue();
 }
Exemplo n.º 10
0
 private void ProcessInstructionThread(RFWorkQueueItem i)
 {
     try
     {
         Log.Debug(this, "Started thread to process instruction {0}", i.Item as RFProcessInstruction);
         var result = _context.Engine.Process(i.Item as RFInstruction, _context.GetProcessingContext(i.ProcessingKey, _instructionSink, _eventSink, this));
         _eventSink.RaiseEvent(this, new RFProcessingFinishedEvent(i, result, null), i.ProcessingKey); // we do not store work queue items in-proc
     }
     catch (Exception ex)
     {
         Log.Exception(this, ex, "Exception Thread processing queue item ", i);
         _eventSink.RaiseEvent(this, new RFProcessingFinishedEvent(i, RFProcessingResult.Error(new string[] { ex.Message }, false), null), i.ProcessingKey);
     }
 }
Exemplo n.º 11
0
        private static bool Filter(RFWorkQueueItem i)
        {
            if (i?.Item != null)
            {
                var type = i.Item.DispatchItemType();
                switch (type)
                {
                case ItemType.NotSupported:
                    return(false);

                default:
                    return(true);
                }
            }
            return(false);
        }
Exemplo n.º 12
0
 public void ProcessingFinished(RFWorkQueueItem i, RFProcessingResult result)
 {
     Monitor.Enter(_sync);
     if (i.Item is RFProcessInstruction)
     {
         _inProgress.Remove(i);//.Item as RFProcessInstruction);
         RFStatic.Log.Debug(typeof(RFGraphDispatchQueue), "Processing finished for {0} ({1} in progress)", i.Item, _inProgress.Count);
         _dispatchStore.Finished(i, result);
     }
     RefreshReadyQueue();
     RefreshInstructionCount();
     if (!InProgress(i.ProcessingKey))
     {
         QueueItem(new RFWorkQueueItem {
             Item = new RFRequestCompleted(), ProcessingKey = i.ProcessingKey
         });                  // notify monitor this request is done
     }
     Monitor.PulseAll(_sync); // inprogress finished and nothing left
     Monitor.Exit(_sync);
 }
Exemplo n.º 13
0
 protected override void ProcessQueueItem(RFWorkQueueItem item)
 {
     _workerQueue.Send(item);
 }
Exemplo n.º 14
0
 protected override void ProcessQueueItem(RFWorkQueueItem item)
 {
     Task.Run(() => ProcessInstructionThread(item), _context.CancellationTokenSource.Token);
 }
Exemplo n.º 15
0
 protected abstract void ProcessQueueItem(RFWorkQueueItem item);
Exemplo n.º 16
0
        public void QueueItem(RFWorkQueueItem i)
        {
            if (i.Item == null)
            {
                throw new RFSystemException(this, "Invalid empty work item received.");
            }
            Monitor.Enter(_sync);

            // ignore if already running or queued (timers)
            if (i.Item is RFProcessInstruction && (_inProgress.Any() || _readyQueue.Any()))
            {
                if (i.Item is RFGraphProcessInstruction)
                {
                    // if one processor subscribes to multiple outputs of another processor duplicate
                    // instruction can happen
                    var gpi     = i.Item as RFGraphProcessInstruction;
                    var running = _inProgress.Where(p => p.Item is RFGraphProcessInstruction).Select(p => p.Item as RFGraphProcessInstruction).ToList();
                    if (running.Any(r => r.Instance.Equals(gpi.Instance) && r.ProcessName == gpi.ProcessName))
                    {
                        RFStatic.Log.Debug(this, "Ignoring instruction {0} for as we have one running already", gpi);
                        return; // ignore already in progress
                    }

                    var ready = _readyQueue.Where(p => p.Item is RFGraphProcessInstruction).Select(p => p.Item as RFGraphProcessInstruction).ToList();
                    if (ready.Any(r => r.Instance.Equals(gpi.Instance) && r.ProcessName == gpi.ProcessName))
                    {
                        RFStatic.Log.Debug(this, "Ignoring instruction {0} for as we have one ready already", gpi);
                        return; // ignore already ready
                    }
                }
                // not sure this was used - probably not since this throws away an instruction rather than delays it

                /*
                 * else
                 * {
                 *  var pi = i.Item as RFProcessInstruction;
                 *  if (pi.Event is RFIntervalEvent) // allow concurrent processing of multiple files or external triggers but not timers
                 *  {
                 *      if (_inProgress.Any())
                 *      {
                 *          var inProgress = _inProgress.Where(q => q.Item is RFProcessInstruction).Select(q => q.Item as RFProcessInstruction);
                 *          if (inProgress.Any(q => q.ProcessName == pi.ProcessName))
                 *          {
                 *              return; // ignore already in progress - for example FTP taking longer than timed trigger
                 *          }
                 *      }
                 *
                 *      if (_readyQueue.Any())
                 *      {
                 *          var queued = _readyQueue.Where(q => q.Item is RFProcessInstruction).Select(q => q.Item as RFProcessInstruction);
                 *          if (queued.Any(q => q.ProcessName == pi.ProcessName))
                 *          {
                 *              return; // ignore already same process queued
                 *          }
                 *      }
                 *  }
                 * }*/
            }

            if (i.Item is RFGraphProcessInstruction)
            {
                var gpi = i.Item as RFGraphProcessInstruction;

                if (gpi.Instance != null && gpi.Instance.ValueDate.HasValue)
                {
                    long datePart = (gpi.Instance.ValueDate.Value.ToYMD() - (long)20000000) * 1000000;

                    if (_processWeights.ContainsKey(gpi.ProcessName))
                    {
                        var weight   = _processWeights[gpi.ProcessName];
                        var queueKey = datePart + weight;
                        if (_pendingInstructions.ContainsKey(queueKey))
                        {
                            var potentialDupes = _pendingInstructions[queueKey].Select(d => d.Item as RFGraphProcessInstruction);

                            // ignore duplicate
                            if (potentialDupes.Any(qi => qi.ProcessName.Equals(gpi.ProcessName) && qi.Instance.Equals(gpi.Instance)))
                            {
                                RFStatic.Log.Debug(this, "Ignoring instruction {0} for as we have one in the queue already", gpi);
                                Monitor.Exit(_sync);
                                return;
                            }
                        }
                        else
                        {
                            _pendingInstructions.Add(queueKey, new List <RFWorkQueueItem>());
                        }

                        _pendingInstructions[queueKey].Add(i);
                        _dispatchStore.Queued(i, queueKey);
                    }
                    else
                    {
                        RFStatic.Log.Info(this, "Assuming zero weighted for unweighted graph instruction {0}/{1}", gpi.ProcessName,
                                          gpi.Instance.ToString());

                        if (!_pendingInstructions.ContainsKey(datePart))
                        {
                            _pendingInstructions.Add(datePart, new List <RFWorkQueueItem>());
                        }
                        _pendingInstructions[datePart].Add(i);
                        _dispatchStore.Queued(i, datePart);
                    }
                }
                else
                {
                    RFStatic.Log.Warning(this, "Received graph instruction for process {0} without instance date.", gpi.ProcessName);
                    if (!_pendingInstructions.ContainsKey(0))
                    {
                        _pendingInstructions.Add(0, new List <RFWorkQueueItem>());
                    }
                    _pendingInstructions[0].Add(i); // no instance date
                    _dispatchStore.Queued(i, 0);
                }
                RefreshReadyQueue();
            }
            else if (i.Item is RFProcessInstruction)
            {
                var pi = i.Item as RFProcessInstruction;
                if (!_pendingInstructions.ContainsKey(0))
                {
                    _pendingInstructions.Add(0, new List <RFWorkQueueItem>());
                }
                // if we already have an identical pending instruction, we ignore (meaning we'll
                // still queue if there's an identical one already *in progress*) the logic here is
                // that if there's been multiple instances of the same event, we only process once
                var potentialDupes = _pendingInstructions[0].Select(p => p.Item as RFProcessInstruction).Where(p => p != null && p.ProcessName == pi.ProcessName);
                if (!potentialDupes.Any(d => RFEngineProcessorParam.Equals(d?.ExtractParam(), pi?.ExtractParam())))
                {
                    _pendingInstructions[0].Add(i); // no instance date
                    _dispatchStore.Queued(i, 0);
                    RefreshReadyQueue();
                }

                /*else
                 * {
                 *  RFStatic.Log.Debug(this, "Ignoring already pending RFProcessInstruction {0}", pi);
                 * }*/
            }
            else
            {
                _readyQueue.Add(i); // straight to readyqueue
                _dispatchStore.Queued(i, 0);
                Monitor.PulseAll(_sync);
            }
            RefreshInstructionCount();
            Monitor.Exit(_sync);
        }
Exemplo n.º 17
0
        protected void ProcessItem(RFWorkQueueItem item)
        {
            if (item != null)
            {
                try
                {
                    var content = item.Item;
                    if (content is RFInstruction i)
                    {
                        if (i.ForceProcessLocally())
                        {
                            // processing results will go directly into our internal queues rather than be distributed
                            var result = _context.Engine.Process(content as RFInstruction, _context.GetProcessingContext(item.ProcessingKey, _instructionSink, _eventSink, this));
                            ProcessingFinished(item, result);
                        }
                        else
                        {
                            Log.Debug(this, "Received instruction {0}", content);

                            ProcessQueueItem(item);
                        }
                    }
                    else if (content is RFEvent)
                    {
                        if (!(content is RFIntervalEvent) && !((content is RFCatalogUpdateEvent) && (content as RFCatalogUpdateEvent).Key.Plane == RFPlane.Ephemeral))
                        {
                            Log.Debug(this, "Received event {0}", content);
                        }
                        if (content is RFProcessingFinishedEvent)
                        {
                            var fe = content as RFProcessingFinishedEvent;

                            RFStatic.Log.Debug(this, "Processing finished event for {0} with {1} events", fe.Item, (fe.WorkQueueItems ?? new RFWorkQueueItem[0]).Length);
                            // queue all resulting events and instructions
                            foreach (var wi in fe.WorkQueueItems ?? new RFWorkQueueItem[0])
                            {
                                if (wi.Item is RFEvent)
                                {
                                    // react to events immediately as they might queue calculations
                                    // and impact calculation order
                                    _context.Engine.React(wi.Item as RFEvent, _context.GetProcessingContext(item.ProcessingKey, _instructionSink, _eventSink, this));
                                }
                                else
                                {
                                    // queue process instructions
                                    _dispatchQueue.QueueItem(wi);
                                }
                            }

                            // this will ensure all processing artifacts are queued before marking
                            // processing as complete (avoid finishing while events still pending)
                            ProcessingFinished(fe.Item, fe.Result);
                        }
                        _context.Engine.React(content as RFEvent, _context.GetProcessingContext(item.ProcessingKey, _instructionSink, _eventSink, this));
                        _dispatchQueue.ProcessingFinished(item, null);
                    }
                }
                catch (Exception ex)
                {
                    Log.Exception(this, ex, "Exception processing queue item ", item);
                }
            }
        }
Exemplo n.º 18
0
 private void ProcessingFinished(RFWorkQueueItem i, RFProcessingResult result)
 {
     _requestTracker.CycleFinished(i, result);
     _dispatchQueue.ProcessingFinished(i, result);
 }