예제 #1
0
 /// <inheritdoc />
 public Task <PlaceFileResult> PlaceFileAsync
 (
     Context context,
     ContentHash contentHash,
     AbsolutePath path,
     FileAccessMode accessMode,
     FileReplacementMode replacementMode,
     FileRealizationMode realizationMode,
     CancellationToken cts,
     UrgencyHint urgencyHint
 )
 {
     return(_contentReadOnlySession.PlaceFileAsync(context, contentHash, path, accessMode, replacementMode, realizationMode, cts, urgencyHint));
 }
예제 #2
0
        /// <inheritdoc />
        public Task <PlaceFileResult> PlaceFileAsync(Context context, FullPath path, VfsFilePlacementData placementData, CancellationToken token)
        {
            return(WithOperationContext(context, token, async operationContext =>
            {
                var result = await operationContext.PerformOperationAsync(
                    Tracer,
                    async() =>
                {
                    var virtualPath = ToVirtualPath(placementData, path);

                    var node = Tree.AddFileNode(virtualPath, placementData, path.Path);

                    var vfsPath = _configuration.VfsRootPath / virtualPath;

                    // TODO: Faster path for getting size of file. Also would be good to batch somehow.
                    // Maybe have FileContentManager batch pin files
                    var pinResult = await _placer.PinAsync(context, node.Hash, operationContext.Token);
                    if (pinResult.ContentSize > 0)
                    {
                        node.Size = pinResult.ContentSize;
                    }
                    else
                    {
                        return new PlaceFileResult($"Pin file size = {pinResult.ContentSize}");
                    }

                    if (placementData.AccessMode == FileAccessMode.ReadOnly)
                    {
                        // NOTE: This should cause the placeholder to get created under vfs root
                        _fileSystem.DenyFileWrites(vfsPath);
                    }

                    var result = _fileSystem.CreateHardLink(vfsPath, path, replaceExisting: true);
                    if (result != CreateHardLinkResult.Success)
                    {
                        if (result == CreateHardLinkResult.FailedDestinationDirectoryDoesNotExist)
                        {
                            _fileSystem.CreateDirectory(path.Parent);
                            result = _fileSystem.CreateHardLink(vfsPath, path, replaceExisting: true);
                        }

                        if (result != CreateHardLinkResult.Success)
                        {
                            return new PlaceFileResult($"Failed to create hardlink: {result}");
                        }
                    }

                    return new PlaceFileResult(GetPlaceResultCode(placementData.RealizationMode, placementData.AccessMode), fileSize: pinResult.ContentSize /* Unknown */);
                },
                    caller: "PlaceVirtualFile",
                    extraEndMessage: r => $"Hash={placementData.Hash}");

                if (!result.Succeeded)
                {
                    return await _placer.PlaceFileAsync(context, path, placementData, token);
                }

                return result;
            }));
        }
 /// <inheritdoc />
 public static Task <PlaceFileResult> PlaceFileAsync(this IReadOnlyContentSession session, Context context, AbsolutePath path, VfsFilePlacementData placementData, CancellationToken token)
 {
     return(session.PlaceFileAsync(
                context,
                placementData.Hash,
                path,
                placementData.AccessMode,
                FileReplacementMode.ReplaceExisting,
                placementData.RealizationMode,
                token));
 }
예제 #4
0
        private async Task PlaceFileAsync(
            IReadOnlyContentSession session, IReadOnlyCollection <Tuple <ContentHash, AbsolutePath> > args, List <PlaceFileResult> results)
        {
            var tasks = args.Select(t => Task.Run(async() => await session.PlaceFileAsync(
                                                      _context,
                                                      t.Item1,
                                                      t.Item2,
                                                      FileAccessMode.ReadOnly,
                                                      FileReplacementMode.FailIfExists,
                                                      FileRealizationMode.HardLink,
                                                      CancellationToken.None)));

            foreach (var task in tasks.ToList())
            {
                var result = await task;
                results.Add(result);
            }
        }