Exemplo n.º 1
0
        public PackageStatusResponse PackageStatus([FromBody] PackageStatusRequest request)
        {
            var result = downloadManager.GetPackageStatusResponse(request.PackageIds);

            return(result);
        }
        private void StatusUpdateInternal()
        {
            PackageStatusRequest requestMessage;

            PeerOverallStatus[] peersToUpdate;
            var elapsed = stopwatch.Elapsed;
            var elapsedThresholdRegular = elapsed.Subtract(settings.PeerUpdateStatusTimer);
            var elapsedThresholdFast    = elapsed.Subtract(settings.PeerUpdateStatusFastTimer);

            // prepare list of peers and list of packages we're interested in
            lock (syncLock)
            {
                if (states.Count == 0)
                {
                    return;
                }

                peersToUpdate = peers.Values
                                .Where(c => c.LastUpdateTry < (c.UseFastUpdate ? elapsedThresholdFast : elapsedThresholdRegular) && c.DoUpdateStatus)
                                .ToArray();

                if (peersToUpdate.Length == 0)
                {
                    return;
                }

                foreach (var item in peersToUpdate)
                {
                    item.UseFastUpdate = false; // reset
                    item.LastUpdateTry = elapsed;
                }

                requestMessage = new PackageStatusRequest()
                {
                    PackageIds = states.Keys.ToArray()
                };
            }

            logger.LogTrace("Sending update request for {0} package(s) to {1} peer(s).", requestMessage.PackageIds.Length, peersToUpdate.Length);

            // build blocks to process and link them
            var fetchClientStatusBlock = new TransformBlock <PeerOverallStatus, (PeerOverallStatus peer, PackageStatusResponse result, bool succes)>(
                p => FetchClientStatusAsync(p, requestMessage),
                new ExecutionDataflowBlockOptions()
            {
                MaxDegreeOfParallelism = ConcurrentStatusUpdates
            }
                );

            var applyClientStatusBlock = new ActionBlock <(PeerOverallStatus peer, PackageStatusResponse result, bool success)>(
                p => ApplyClientStatus(p, requestMessage),
                new ExecutionDataflowBlockOptions()
            {
                MaxDegreeOfParallelism = 1
            }
                );

            fetchClientStatusBlock.LinkTo(applyClientStatusBlock, new DataflowLinkOptions()
            {
                PropagateCompletion = true
            });

            // send
            foreach (var peerToUpdate in peersToUpdate)
            {
                fetchClientStatusBlock.Post(peerToUpdate);
            }
            fetchClientStatusBlock.Complete();
            applyClientStatusBlock.Completion.Wait();


            // apply downloads
            NewDataAvailable?.Invoke();
        }