public void QueueInstruction(object issuedBy, RFInstruction i, string processingKey) { _destinationQueue.QueueItem(new RFWorkQueueItem { Item = i, ProcessingKey = processingKey }); if (i.ExtractParam() is RFEngineProcessorKeyParam) { // don't log interval updates if ((i.ExtractParam() as RFEngineProcessorKeyParam)?.Key.Plane == RFPlane.Ephemeral) { return; } } RFStatic.Log.LogInstruction(issuedBy, i); }
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); } } }