Пример #1
0
        public (Stream stream, DataResponseFaul error) CreateUploadStream(LocalPackageInfo package, int[] requestedSegments)
        {
            if (package == null)
            {
                throw new ArgumentNullException(nameof(package));
            }

            if (requestedSegments == null)
            {
                throw new ArgumentNullException(nameof(requestedSegments));
            }

            // packages ok?
            if (!package.DownloadStatus.ValidateRequestedParts(requestedSegments))
            {
                logger.LogTrace($"Requested segments not valid for {package}: {requestedSegments.Format()}");
                return(null, DataResponseFaul.CreateDataPackageSegmentsNotFoundMessage());
            }

            // allocate slot
            int newUploadSlotsCount = Interlocked.Decrement(ref uploadSlots);

            if (newUploadSlotsCount <= 0)
            {
                // not enough slots
                Interlocked.Increment(ref uploadSlots);
                logger.LogTrace($"Peer choked when requested {package} segments: {requestedSegments.Format()}");
                return(null, DataResponseFaul.CreateChokeMessage());
            }

            // obtain lock
            if (!package.LockProvider.TryLock(out object lockToken))
            {
                return(null, DataResponseFaul.CreateDataPackageNotFoundMessage());
            }

            // create reader stream
            var sequencer = new PackagePartsSequencer();

            logger.LogTrace($"Uploading for {package} segments: {requestedSegments.Format()}");
            IEnumerable <PackageDataStreamPart> partsSource = sequencer.GetPartsForSpecificSegments(package.Reference.FolderPath, package.Sequence, requestedSegments);
            var controller = new ReadPackageDataStreamController(appInfo.LoggerFactory, package.Reference, package.Sequence, partsSource);
            var stream     = new PackageDataStream(appInfo.LoggerFactory, controller)
            {
                Measure = package.UploadMeasure
            };

            stream.Disposing += () => {
                int currentSlots = Interlocked.Increment(ref uploadSlots);
                package.LockProvider.Unlock(lockToken);
            };
            return(stream, null);
        }
Пример #2
0
        public IActionResult Data([FromBody] DataRequest request)
        {
            if (!packageRegistry.TryGetPackage(request.PackageHash, out LocalPackageInfo package) || package.LockProvider.IsMarkedToDelete)
            {
                return(new ObjectResult(DataResponseFaul.CreateDataPackageNotFoundMessage()));
            }

            // create stream
            var result = peersCluster.CreateUploadStream(package, request.RequestedParts);

            if (result.error != null)
            {
                return(new ObjectResult(result.error));
            }
            return(new FileStreamResult(result.stream, "application/octet-stream"));
        }