Example #1
0
        public async Task <PlaceFileResult> CreateTempAndPutAsync(
            OperationContext context,
            ContentHash contentHash,
            IContentSession contentSession)
        {
            using (var disposableFile = new DisposableFile(context, _fileSystem, AbsolutePath.CreateRandomFileName(_rootPath / "temp")))
            {
                PlaceFileResult placeTempFileResult = await PlaceFileAsync(context, contentHash, disposableFile.Path, FileAccessMode.ReadOnly, FileReplacementMode.FailIfExists, FileRealizationMode.HardLink, context.Token);

                if (!placeTempFileResult.Succeeded)
                {
                    return(placeTempFileResult);
                }
                PutResult putFileResult = await contentSession.PutFileAsync(context, contentHash, disposableFile.Path, FileRealizationMode.Any, context.Token);

                if (!putFileResult)
                {
                    return(new PlaceFileResult(putFileResult));
                }
                else
                {
                    return(new PlaceFileResult(PlaceFileResult.ResultCode.PlacedWithCopy, putFileResult.ContentSize));
                }
            }
        }
Example #2
0
        public virtual async Task <PushFileResult> PushFileAsync(OperationContext context, ContentHash hash, Stream stream, MachineLocation targetMachine, CopyOptions options)
        {
            var tempFile = AbsolutePath.CreateRandomFileName(WorkingDirectory);

            using (var file = File.OpenWrite(tempFile.Path))
            {
                await stream.CopyToAsync(file);
            }

            var result = await PushHandlersByLocation[targetMachine].HandlePushFileAsync(context, hash, tempFile, CancellationToken.None);

            File.Delete(tempFile.Path);

            return(result ? PushFileResult.PushSucceeded(result.ContentSize) : new PushFileResult(result));
        }
Example #3
0
        /// <summary>
        /// Handles a request to copy content to this machine.
        /// </summary>
        public async Task HandlePushFileAsync(IAsyncStreamReader <PushFileRequest> requestStream, IServerStreamWriter <PushFileResponse> responseStream, ServerCallContext callContext)
        {
            OperationStarted();

            var startTime = DateTime.UtcNow;

            var pushRequest = PushRequest.FromMetadata(callContext.RequestHeaders);

            var hash         = pushRequest.Hash;
            var cacheContext = new Context(pushRequest.TraceId, Logger);
            var token        = callContext.CancellationToken;

            var store = _contentStoreByCacheName.Values.OfType <IPushFileHandler>().FirstOrDefault();

            if (store == null)
            {
                Tracer.Debug(cacheContext, $"{nameof(HandlePushFileAsync)}: Copy of {hash.ToShortString()} skipped because no stores implement {nameof(IPushFileHandler)}.");
                await callContext.WriteResponseHeadersAsync(PushResponse.DontCopy.Metadata);

                return;
            }

            if (store.HasContentLocally(cacheContext, hash))
            {
                Tracer.Debug(cacheContext, $"{nameof(HandlePushFileAsync)}: Copy of {hash.ToShortString()} skipped because content is already local.");
                await callContext.WriteResponseHeadersAsync(PushResponse.DontCopy.Metadata);

                return;
            }

            if (!_ongoingPushes.Add(hash))
            {
                Tracer.Debug(cacheContext, $"{nameof(HandlePushFileAsync)}: Copy of {hash.ToShortString()} skipped because another request to push it is already being handled.");
                await callContext.WriteResponseHeadersAsync(PushResponse.DontCopy.Metadata);

                return;
            }

            try
            {
                await callContext.WriteResponseHeadersAsync(PushResponse.Copy.Metadata);

                var tempFilePath = AbsolutePath.CreateRandomFileName(_tempDirectory);

                using (var tempFile = File.OpenWrite(tempFilePath.Path))
                {
                    while (await requestStream.MoveNext())
                    {
                        if (token.IsCancellationRequested)
                        {
                            return;
                        }

                        var request = requestStream.Current;
                        var bytes   = request.Content.ToByteArray();
                        await tempFile.WriteAsync(bytes, 0, bytes.Length);
                    }
                }

                var result = await store.HandlePushFileAsync(cacheContext, hash, tempFilePath, token);

                File.Delete(tempFilePath.Path);

                var response = result
                    ? new PushFileResponse {
                    Header = ResponseHeader.Success(startTime)
                }
                    : new PushFileResponse {
                    Header = ResponseHeader.Failure(startTime, result.ErrorMessage)
                };

                await responseStream.WriteAsync(response);
            }
            finally
            {
                _ongoingPushes.Remove(hash);
            }
        }