示例#1
0
 private void CompleteRange(DataProcessingContext ctx)
 {
     foreach (var item in ctx.ReservedRange.DataNodeToFinalParts)
     {
         if (this.dataNodeReadersPool.TryGetReader(item.Key, out var dataReader))
         {
             dataReader.Complete(item.Value, ctx.CancellationToken);
         }
         else
         {
             this.InstrumentateNoReaderForDef(item.Key, "Не найден DataReader для завершения обработки");
         }
     }
 }
示例#2
0
        private void ReserveRange(DataNodeReader nodeReader, DataProcessingContext ctx)
        {
            ReservedRange range = nodeReader.ReserveRangeAsync(ctx.DpuId, new ReserveRangeOptions
            {
                LeaseTimeout                = this.settings.JobLeaseLifeTime ?? TimeSpan.FromHours(1),
                NeedReserveRange            = ctx.NeedReserveRange.ForAlreadyReserved(ctx.RangeRecordsCount()),
                HasDataInPreviousProcessing = ctx.HasDataInPreviousProcessing,
                FullScanAfterNQueries       = 20,
            }, ctx.CancellationToken);

            if (ctx.ReservedRange == null)
            {
                ctx.ReservedRange = range;
            }
            else
            {
                ctx.ReservedRange.Add(range);
            }
        }
示例#3
0
        private void ProcessRange(DataProcessingContext ctx)
        {
            ctx.CancellationToken.ThrowIfCancellationRequested();

            // TODO стоит сделать что-нить более удобное...
            foreach (var nodeToPacketsParts in ctx.ReservedRange.DataNodeToFinalParts)
            {
                ctx.CancellationToken.ThrowIfCancellationRequested();

                foreach (var providerGrouping in nodeToPacketsParts.Value
                         .OrderBy(x => x.PacketId)
                         .GroupBy(x => x.ProviderKey))
                {
                    // если отсутствуют работющие процессоры то не обрабатываем
                    if (this.HasWorkingProcessors(providerGrouping.Key))
                    {
                        this.FillPacketsInfosChains(nodeToPacketsParts.Key, providerGrouping, ctx);
                        this.ProcessForProvider(providerGrouping.Key, providerGrouping, ctx);
                    }
                }
            }
        }
示例#4
0
        private void ReserveRange(DataProcessingContext ctx)
        {
            ctx.CancellationToken.ThrowIfCancellationRequested();

            foreach (var node in ctx.OrderedNodes)
            {
                if (this.dataNodeReadersPool.TryGetReader(node, out var dataReader))
                {
                    this.ReserveRange(dataReader, ctx);
                }
                else
                {
                    this.InstrumentateNoReaderForDef(node, "Не найден DataReader для резервирования записей для обработки");
                }
                if (ctx.ReservedRange != null && ctx.IsRangeFilled())
                {
                    break;
                }
                else
                {
                }
            }
        }
示例#5
0
        private void ProcessForProvider(string providerKey, IEnumerable <AgentPacketPartInfo> providerFinalPacketParts, DataProcessingContext ctx)
        {
            ctx.CancellationToken.ThrowIfCancellationRequested();

            if (this.processorContainers.TryGetValue(providerKey, out var processorContainers))
            {
                foreach (var packetPartBatch in providerFinalPacketParts.Batch(20))
                {
                    ctx.CancellationToken.ThrowIfCancellationRequested();
                    var computerPackets = new List <ComputerPacket>();
                    try
                    {
                        var packetToBytes = this.GetBytesForPacketChains(packetPartBatch, ctx);

                        foreach (var packetPart in packetPartBatch)
                        {
                            if (packetToBytes.TryGetValue(packetPart, out var packetBytes))
                            {
                                Stream stream = null;
                                try
                                {
                                    stream = new MemoryStream(packetBytes, false);
                                    computerPackets.Add(new ComputerPacket(packetPart.AgentInfo.ToComputerIdentity(), stream));
                                }
                                catch (Exception)
                                {
                                    stream?.Dispose();
                                    throw;
                                }
                            }
                            else
                            {
                                // TODO instrumentation
                            }
                        }

                        using (var packetProcessorsContext = new PacketProcessorsContext())
                        {
                            foreach (var processorContainer in processorContainers)
                            {
                                ctx.CancellationToken.ThrowIfCancellationRequested();

                                if (processorContainer.CanProcess)
                                {
                                    foreach (var computerPacket in computerPackets)
                                    {
                                        computerPacket.Stream.Seek(0, SeekOrigin.Begin);
                                    }

                                    try
                                    {
                                        processorContainer.Processor.Process(computerPackets, packetProcessorsContext, ctx.CancellationToken);
                                    }
                                    catch (OperationCanceledException)
                                    {
                                        ctx.CancellationToken.ThrowIfCancellationRequested();
                                    }
                                    catch (Exception)
                                    {
                                        // TODO instrumentation
                                    }
                                }
                            }
                        }
                    }
                    finally
                    {
                        foreach (var computerPacket in computerPackets)
                        {
                            computerPacket.Stream.Dispose();
                        }
                    }
                }
            }
            else
            {
                // TODO instrumentation
                this.InstrumentateNoProcessorsForProvider(providerKey, providerFinalPacketParts);
            }
        }
示例#6
0
        private IDictionary <AgentPacketPartInfo, byte[]> GetBytesForPacketChains(IEnumerable <AgentPacketPartInfo> finalPacketParts, DataProcessingContext ctx)
        {
            var dict = new Dictionary <AgentPacketPartInfo, byte[]>();
            var packetPartToBytesDict = new Dictionary <PacketPartInfo, byte[]>();

            var chains = finalPacketParts.Select(x => ctx.PacketToChain.TryGetValue(x, out var chain) ? chain : null).Where(x => x != null);
            var packetPairsGroupByNode = chains.SelectMany(x => x).GroupBy(x => x.NodeDefinition);

            // получаем байты всех частей
            foreach (var nodePacketPairsGroup in packetPairsGroupByNode)
            {
                if (this.dataNodeReadersPool.TryGetReader(nodePacketPairsGroup.Key, out var reader))
                {
                    var idToByteDict = reader.GetPacketPartInfoBytes(nodePacketPairsGroup.Select(x => x.PacketPartInfo.Id), ctx.CancellationToken);
                    foreach (var item in nodePacketPairsGroup)
                    {
                        if (idToByteDict.TryGetValue(item.PacketPartInfo.Id, out var bytes))
                        {
                            packetPartToBytesDict.Add(item.PacketPartInfo, bytes);
                        }
                    }
                }
                else
                {
                    // TODO instrumentation
                    this.InstrumentateNoReaderForDef(nodePacketPairsGroup.Key, "Не найден DataReader для получения бинарных данных записей для обработки");
                }
            }

            // собираем финальный словарь
            foreach (var finalPacketPart in finalPacketParts)
            {
                if (ctx.PacketToChain.TryGetValue(finalPacketPart, out var chain))
                {
                    var partBytes = new List <byte[]>(chain.Count);
                    foreach (var part in chain)
                    {
                        if (packetPartToBytesDict.TryGetValue(part.PacketPartInfo, out var bytes))
                        {
                            partBytes.Add(bytes);
                        }
                        else
                        {
                            partBytes = null;
                            break;
                        }
                    }

                    if (partBytes != null)
                    {
                        dict.Add(finalPacketPart, partBytes.SelectMany(x => x).ToArray());
                    }
                }
            }

            return(dict);
        }
示例#7
0
        // TODO можно собирать PacketPartNodePair не по одной записи, а для всей пачки
        // для пакетов которые разбиты на части
        private void FillNonFullParts(IList <AgentPacketPartNodePair> nonFullPartToNodes, DataProcessingContext ctx)
        {
            var cache = new List <PacketPartNodePair>();
            var checkedStoreTokens = new List <string>();

            foreach (var part in nonFullPartToNodes)
            {
                ctx.CancellationToken.ThrowIfCancellationRequested();

                PacketPartNodePair currentPartInfo = part.ToPacketPartNodePair();

                var chains = new Stack <List <PacketPartNodePair> >();
                chains.Push(new List <PacketPartNodePair>()
                {
                    currentPartInfo
                });

                List <PacketPartNodePair> completedChain = null;
                List <PacketPartNodePair> currentChain;
                while (chains.Any() && (currentChain = chains.Pop()) != null)
                {
                    var results = currentChain;
                    currentPartInfo = currentChain.Last();
                    while (currentPartInfo != null && currentPartInfo.PacketPartInfo.PreviousPartId != null)
                    {
                        ctx.CancellationToken.ThrowIfCancellationRequested();
                        if (currentPartInfo.PacketPartInfo.PreviousPartStorageToken == null)
                        {
                            // непонятная ситуация - ошибка
                            currentPartInfo = null;
                            results         = null;
                            break;
                        }

                        var currentPartInfos = cache.Where(x => x.PacketPartInfo.Id == currentPartInfo.PacketPartInfo.PreviousPartId);
                        if (!currentPartInfos.Any())
                        {
                            // добавляем в кэш только один раз
                            if (!checkedStoreTokens.Contains(currentPartInfo.PacketPartInfo.PreviousPartStorageToken) && this.dataNodeReadersPool.TryGetReaderForStorageId(currentPartInfo.PacketPartInfo.PreviousPartStorageToken, out var reader))
                            {
                                var infos = reader.GetPacketPartInfos(nonFullPartToNodes.Select(x => x.PacketPartInfo.PacketId).ToList(), ctx.CancellationToken);
                                foreach (var item in infos)
                                {
                                    cache.Add(new PacketPartNodePair
                                    {
                                        PacketPartInfo = item,
                                        NodeDefinition = reader.nodeDefinition,
                                    });
                                }
                                checkedStoreTokens.Add(currentPartInfo.PacketPartInfo.PreviousPartStorageToken);
                                currentPartInfos = cache.Where(x => x.PacketPartInfo.Id == currentPartInfo.PacketPartInfo.PreviousPartId);
                            }
                            else
                            {
                                this.InstrumentateNoReaderForStorageToken(currentPartInfo.PacketPartInfo.PreviousPartStorageToken, "");
                            }
                        }

                        if (currentPartInfos.Any())
                        {
                            currentPartInfo = currentPartInfos.First();
                            results.Add(currentPartInfo);
                            foreach (var item in currentPartInfos.Skip(1))
                            {
                                var chain = results.ToList();
                                chain.Add(item);
                                chains.Push(chain);
                            }
                        }
                        else
                        {
                            // TODO instrumentation
                            currentPartInfo = null;
                            results         = null;
                        }
                    }

                    if (this.CheckCompletedChain(results))
                    {
                        results.Reverse();
                        completedChain = results;
                        break;
                    }
                }

                if (completedChain != null)
                {
                    ctx.PacketToChain.Add(part.PacketPartInfo, completedChain);
                }
                else
                {
                    // TODO instrumentation
                }
            }
        }
示例#8
0
        private void FillPacketsInfosChains(DataNodeDefinition node, IEnumerable <AgentPacketPartInfo> providerFinalPacketParts, DataProcessingContext ctx)
        {
            ctx.CancellationToken.ThrowIfCancellationRequested();

            var partedFinalParts = new List <AgentPacketPartNodePair>();

            if (this.dataNodeReadersPool.TryGetReader(node, out var dataReader))
            {
                foreach (var packetFinalPartInfo in providerFinalPacketParts)
                {
                    ctx.CancellationToken.ThrowIfCancellationRequested();

                    // для частей которые содержат весь пакет
                    if (packetFinalPartInfo.StartPosition == 0)
                    {
                        ctx.PacketToChain.Add(packetFinalPartInfo, new List <PacketPartNodePair> {
                            new PacketPartNodePair
                            {
                                NodeDefinition = node,
                                PacketPartInfo = packetFinalPartInfo,
                            }
                        });
                        //ctx.PacketToStreamFactory.Add(packetFinalPartInfo, (token) => new MemoryStream(this.GetBytes(node, packetFinalPartInfo, token), false));
                    }
                    else
                    {
                        partedFinalParts.Add(new AgentPacketPartNodePair
                        {
                            NodeDefinition = node,
                            PacketPartInfo = packetFinalPartInfo,
                        });
                    }
                }
            }
            else
            {
                this.InstrumentateNoReaderForDef(node, "Не найден DataReader для скачивания");
            }

            // для пакетов которые разбиты на части
            this.FillNonFullParts(partedFinalParts, ctx);
        }
示例#9
0
        private void Processing()
        {
            var cancellationToken = this.cancellationTokenSource.Token;

            this.Init(cancellationToken);

            TimeSpan minDelay     = TimeSpan.FromSeconds(3);
            TimeSpan maxDelay     = TimeSpan.FromSeconds(10);
            TimeSpan delayStep    = TimeSpan.FromSeconds(1);
            TimeSpan currentDelay = minDelay;

            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    bool canSuspend = false;
                    using (var cancelationSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                    {
                        // таймаут ?
                        //cancelationSource.CancelAfter

                        var dpuId = this.dpuIdProvider.GetId();
                        // NeedReserveCount можно считать на основе оперативки ?
                        //    PerformanceCounter ramCounter;
                        //    ramCounter = new PerformanceCounter("Memory", "Available MBytes");
                        //    ramCounter.NextValue();

                        var context = new DataProcessingContext
                        {
                            DpuId             = dpuId,
                            OrderedNodes      = this.GetDataNodesOrderedForQuering(),
                            CancellationToken = cancelationSource.Token,
                            NeedReserveRange  = this.settings.ReservationRangeLimits,
                            LoadedInMemoryBinaryPartsBatchSize = this.settings.LoadedInMemoryBinaryPartsBatchSize,
                            HasDataInPreviousProcessing        = !canSuspend,
                        };

                        var stopWatch = Stopwatch.StartNew();
                        this.ReserveRange(context);
                        var reservedTime = stopWatch.Elapsed;
                        if (context.HasDataToProcess)
                        {
                            this.ProcessRange(context);
                            var processedTime = stopWatch.Elapsed - reservedTime;
                            this.CompleteRange(context);
                            var completeRangeTime = stopWatch.Elapsed - processedTime - reservedTime;
                            Debug.WriteLine($"timings: {reservedTime}, {processedTime}, {completeRangeTime}");
                            canSuspend = false;
                        }
                        else
                        {
                            canSuspend = true;
                        }


                        if (canSuspend)
                        {
                            Debug.WriteLine($"processing without suspention ended, time spent - {stopWatch.Elapsed}");
                            if (!context.HasDataInPreviousProcessing)
                            {
                                if (currentDelay < maxDelay)
                                {
                                    currentDelay += delayStep;
                                }
                            }
                        }
                        else
                        {
                            currentDelay = minDelay;
                        }
                    }

                    // возможность приостановить цикл, если не было данных для обработки
                    if (canSuspend)
                    {
                        Task.Delay(currentDelay, cancellationToken).Wait(cancellationToken);
                    }
                }
                catch (OperationCanceledException)
                {
                    // TODO Instrumentation
                }
                catch (Exception)
                {
                    // ignore
                    // TODO Instrumentation
                }
            }
        }