Exemple #1
0
        internal static void HandleAbsoluteTimeTriggers(IpiSensorNetConfiguration moduleConfiguration, IReadOnlyDictionary <TriggerSourceTypeEnum, ITriggerSourceHandler> triggerHandlers, IReadOnlyDictionary <int, TriggerDelegate> triggerDelegates, ConcurrentQueue <TriggerSource> absoluteTimeTriggers, Action <string> logger, IReadOnlyDictionary <TriggerDependencyTypeEnum, ITriggerDependencyHandler> triggerDependencyHandlers)
        {
            if (absoluteTimeTriggers.Count == 0)
            {
                return;
            }

            logger("HandleAbsoluteTimeTriggers: Start...");

            using (var context = PiSensorNetDbContext.Connect(moduleConfiguration.ConnectionString))
            {
                var handlerContext = new TriggerSourceHandlerHelperContext(context, triggerHandlers, triggerDelegates, triggerDependencyHandlers, DateTime.Now);

                while (absoluteTimeTriggers.Count > 0)
                {
                    TriggerSource triggerSource;

                    if (absoluteTimeTriggers.TryDequeue(out triggerSource))
                    {
                        continue;
                    }

                    logger($"HandleAbsoluteTimeTriggers: Handling trigger source #{triggerSource.ID}...");

                    TriggerSourceHandlerHelper.Handle(handlerContext, triggerSource);
                }
            }

            logger($"HandleAbsoluteTimeTriggers: Finished handling {absoluteTimeTriggers.Count} trigger source(s)!");
        }
Exemple #2
0
        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);
        }