internal static bool HandlePackets(PiSensorNetDbContext context, IpiSensorNetConfiguration moduleConfiguration, IReadOnlyMap <FunctionTypeEnum, int> functionTypes, IReadOnlyMap <string, int> functionNames, IReadOnlyDictionary <FunctionTypeEnum, IFunctionHandler> functionHandlers, IReadOnlyDictionary <FunctionTypeEnum, IQueryableFunctionHandler> queryableFunctionHandlers, IReadOnlyDictionary <TriggerSourceTypeEnum, ITriggerSourceHandler> triggerSourceHandlers, IReadOnlyDictionary <int, TriggerDelegate> triggerDelegates, IReadOnlyDictionary <TriggerDependencyTypeEnum, ITriggerDependencyHandler> triggerDependencyHandlers, int?serialProcessID, IHubProxy hubProxy, Action <string> logger) { logger("HandlePackets: Start..."); var packets = context.Packets .Include(i => i.Module) .Include(i => i.Function) .Where(i => i.State == PacketStateEnum.New) .Where(i => i.FunctionID.HasValue) .OrderBy(i => i.Received) .ToList(); logger("HandlePackets: Done selecting..."); // ~21ms if (packets.Count == 0) { return(false); } var handlerContext = new FunctionHandlerContext(moduleConfiguration, context, queryableFunctionHandlers, functionTypes, functionNames, triggerSourceHandlers, triggerDelegates, triggerDependencyHandlers, DateTime.Now); var handleAgain = false; var newMesagesAdded = false; var hubTasksQueue = new HubMessageQueue(); foreach (var packet in packets) { // ReSharper disable once PossibleInvalidOperationException var handler = functionHandlers.GetValueOrDefault(packet.Function.FunctionType); if (handler == null) { context.EnqueueUpdate <Packet>( i => i.State == PacketStateEnum.Unhandled, i => i.ID == packet.ID); logger($"HandlePackets: Packet #{packet.ID} (function '{packet.Function.FunctionType}') could not be handled, no handler found!"); continue; } var functionHandlerResult = handler.IsModuleIdentityRequired && packet.Module.State != ModuleStateEnum.Identified ? PacketStateEnum.Skipped : handler.Handle(handlerContext, packet, ref hubTasksQueue); handleAgain = handleAgain || functionHandlerResult.ShouldHandlePacketsAgain; newMesagesAdded = newMesagesAdded || functionHandlerResult.NewMessagesAdded; context.EnqueueUpdate <Packet>( i => i.State == functionHandlerResult.PacketState && i.Processed == DateTime.Now, i => i.ID == packet.ID); if (handler.TriggerSourceType.HasValue && functionHandlerResult.PacketState == PacketStateEnum.Handled) { TriggerSources[handler.TriggerSourceType.Value].Each(i => TriggerSourceHandlerHelper.Handle(handlerContext, i, packet.Module.ID)); } logger($"HandlePackets: Packet #{packet.ID} processed to '{functionHandlerResult.PacketState}'" + $"{(functionHandlerResult.NewMessagesAdded ? ", new messaged were added" : String.Empty)}" + $"{(functionHandlerResult.ShouldHandlePacketsAgain ? ", requested another handling" : String.Empty)}" + "!"); } logger($"HandlePackets: Done handling packets, processed {packets.Count}!"); // ~51ms context.ExecuteRaw(); logger("HandlePackets: Queries executed!"); // ~13ms if (newMesagesAdded && serialProcessID.HasValue) { Signal.Send(serialProcessID.Value, SignalTypeEnum.User1); } while (hubTasksQueue.Count > 0) { hubProxy.SafeInvoke(hubTasksQueue.Dequeue()); } logger($"HandlePackets: Hub message(s) sent{(newMesagesAdded ? ", Serial signaled about new message(s)" : String.Empty)}{(handleAgain ? ", packet(s) will be handled again" : String.Empty)}!"); // ~10ms return(handleAgain); }