Beispiel #1
0
        public static async Task <PutResult> PutRandomAsync(
            this IContentSession session,
            Context context,
            HashType hashType,
            bool provideHash,
            long size,
            CancellationToken ct)
        {
            Contract.RequiresNotNull(session);
            Contract.RequiresNotNull(context);

            var c = context.CreateNested();

            // TODO: Fix this to work with size > int.Max (bug 1365340)
            var data = ThreadSafeRandom.GetBytes((int)size);

            using (var stream = new MemoryStream(data))
            {
                if (!provideHash)
                {
                    return(await session.PutStreamAsync(c, hashType, stream, ct).ConfigureAwait(false));
                }

                var hash = HashInfoLookup.Find(hashType).CreateContentHasher().GetContentHash(data);
                return(await session.PutStreamAsync(c, hash, stream, ct).ConfigureAwait(false));
            }
        }
Beispiel #2
0
 /// <inheritdoc />
 public Task <PutResult> PutStreamAsync(
     Context context,
     HashType hashType,
     Stream stream,
     CancellationToken cts,
     UrgencyHint urgencyHint = UrgencyHint.Nominal)
 {
     return(_sessionForStream.PutStreamAsync(context, hashType, stream, cts, urgencyHint));
 }
        public async Task PutStreamSucceedsWithNonSeekableStream()
        {
            using (var testDirectory = new DisposableDirectory(FileSystem))
            {
                var rootPath = testDirectory.Path;
                var config   = CreateStoreConfiguration();
                config.Write(FileSystem, rootPath);

                using (var store = CreateStore(testDirectory, config))
                {
                    try
                    {
                        var r = await store.StartupAsync(_context);

                        r.ShouldBeSuccess();

                        IContentSession session1 = null;

                        try
                        {
                            var createSessionResult1 = store.CreateSession(_context, "session1", ImplicitPin.None);
                            createSessionResult1.ShouldBeSuccess();

                            using (createSessionResult1.Session)
                            {
                                var r1 = await createSessionResult1.Session.StartupAsync(_context);

                                r1.ShouldBeSuccess();
                                session1 = createSessionResult1.Session;

                                using (var memoryStream = new RestrictedMemoryStream(ThreadSafeRandom.GetBytes(RandomContentByteCount)))
                                {
                                    var result = await session1.PutStreamAsync(_context, ContentHashType, memoryStream, Token);

                                    result.ShouldBeSuccess();
                                    result.ContentSize.Should().Be(RandomContentByteCount);
                                }
                            }
                        }
                        finally
                        {
                            if (session1 != null)
                            {
                                await session1.ShutdownAsync(_context).ShouldBeSuccess();
                            }
                        }
                    }
                    finally
                    {
                        var r = await store.ShutdownAsync(_context);

                        r.ShouldBeSuccess();
                    }
                }
            }
        }
Beispiel #4
0
        private async Task UploadContent(
            Context context, ContentHash contentHash, IContentSession fromSession, IContentSession toSession)
        {
            var openStreamResult = await fromSession.OpenStreamAsync(context, contentHash, Token).ConfigureAwait(false);

            openStreamResult.Succeeded.Should().BeTrue();
            var putResult = await toSession.PutStreamAsync(context, contentHash, openStreamResult.Stream, Token).ConfigureAwait(false);

            putResult.Succeeded.Should().BeTrue();
        }
Beispiel #5
0
        private Task <PutResult> EnsureLocalAsync(OperationContext context, ContentHash hash)
        {
            return(context.PerformOperationAsync(
                       Tracer,
                       async() =>
            {
                var streamResult = await BackingSession.OpenStreamAsync(context, hash, context.Token).ThrowIfFailure();

                return await WritableLocalSession.PutStreamAsync(context, hash, streamResult.Stream, context.Token);
            }));
        }
Beispiel #6
0
        private async Task PutStreamAsync(
            IContentSession session, IReadOnlyCollection <Stream> streams, List <PutResult> results)
        {
            var tasks = streams.Select(s => Task.Run(async() =>
                                                     await session.PutStreamAsync(_context, ContentHashType, s, CancellationToken.None)));

            foreach (var task in tasks.ToList())
            {
                var result = await task;
                results.Add(result);
            }
        }
Beispiel #7
0
        public static async Task <PutResult> PutContentAsync(
            this IContentSession session, Context context, string content)
        {
            var c = context.CreateNested();

            var data     = Encoding.UTF8.GetBytes(content);
            var hashType = HashType.SHA256;

            using (var stream = new MemoryStream(data))
            {
                var hash = HashInfoLookup.Find(hashType).CreateContentHasher().GetContentHash(data);
                return(await session.PutStreamAsync(c, hash, stream, CancellationToken.None).ConfigureAwait(false));
            }
        }
        /// <inheritdoc />
        public Task <PlaceFileResult> PlaceFileAsync(
            Context context,
            ContentHash contentHash,
            AbsolutePath path,
            FileAccessMode accessMode,
            FileReplacementMode replacementMode,
            FileRealizationMode realizationMode,
            CancellationToken cts,
            UrgencyHint urgencyHint = UrgencyHint.Nominal)
        {
            IContentSession hardlinkSession = null;

            if (realizationMode == FileRealizationMode.HardLink)
            {
                var drive = path.GetPathRoot();
                if (SessionsByCacheRoot.TryGetValue(drive, out var session) && session is IContentSession writeableSession)
                {
                    hardlinkSession = writeableSession;
                }
                else
                {
                    return(Task.FromResult(new PlaceFileResult("Requested hardlink but there is no session on the same drive as destination path.")));
                }
            }

            return(PerformAggregateSessionOperationAsync <IReadOnlyContentSession, PlaceFileResult>(
                       context,
                       executeAsync: placeFileCore,
                       (r1, r2) => r1.Succeeded ? r1 : r2,
                       shouldBreak: r => r.Succeeded,
                       pathHint: path));

            async Task <PlaceFileResult> placeFileCore(IReadOnlyContentSession session)
            {
                // If we exclusively want a hardlink, we should make sure that we can copy from other drives to satisfy the request.
                if (realizationMode != FileRealizationMode.HardLink || session == hardlinkSession)
                {
                    return(await session.PlaceFileAsync(context, contentHash, path, accessMode, replacementMode, realizationMode, cts, urgencyHint));
                }

                // See if session has the content.
                var streamResult = await session.OpenStreamAsync(context, contentHash, cts, urgencyHint).ThrowIfFailure();

                // Put it into correct store
                var putResult = await hardlinkSession.PutStreamAsync(context, contentHash, streamResult.Stream, cts, urgencyHint).ThrowIfFailure();

                // Try the hardlink on the correct drive.
                return(await hardlinkSession.PlaceFileAsync(context, contentHash, path, accessMode, replacementMode, realizationMode, cts, urgencyHint));
            }
        }
        /// <inheritdoc />
        public async Task <ObjectResult <ContentHashListWithCacheMetadata> > AddContentHashListAsync(
            Context context,
            string cacheNamespace,
            StrongFingerprint strongFingerprint,
            ContentHashListWithCacheMetadata valueToAdd)
        {
            try
            {
                Func <System.IO.Stream, System.Threading.CancellationToken, Task <StructResult <ContentHash> > > putStreamFunc =
                    async(stream, cts) =>
                {
                    PutResult putResult = await _blobContentSession.PutStreamAsync(context, HashType.Vso0, stream, cts);

                    if (putResult.Succeeded)
                    {
                        return(new StructResult <ContentHash>(putResult.ContentHash));
                    }

                    return(new StructResult <ContentHash>(putResult));
                };

                StructResult <ContentHash> blobIdOfContentHashListResult =
                    await BlobContentHashListExtensions.PackInBlob(
                        putStreamFunc,
                        valueToAdd.ContentHashListWithDeterminism);

                if (!blobIdOfContentHashListResult.Succeeded)
                {
                    return(new ObjectResult <ContentHashListWithCacheMetadata>(blobIdOfContentHashListResult));
                }

                var blobContentHashListWithDeterminism =
                    new BlobContentHashListWithDeterminism(
                        valueToAdd.ContentHashListWithDeterminism.Determinism.EffectiveGuid,
                        BlobIdentifierToContentHashExtensions.ToBlobIdentifier(blobIdOfContentHashListResult.Data));

                var blobContentHashListWithCacheMetadata = new BlobContentHashListWithCacheMetadata(
                    blobContentHashListWithDeterminism,
                    valueToAdd.GetRawExpirationTimeUtc(),
                    valueToAdd.ContentGuarantee,
                    valueToAdd.HashOfExistingContentHashList);

                BlobContentHashListResponse addResult = await ArtifactHttpClientErrorDetectionStrategy.ExecuteWithTimeoutAsync(
                    context,
                    "AddContentHashList",
                    innerCts => _buildCacheHttpClient.AddContentHashListAsync(
                        cacheNamespace,
                        strongFingerprint,
                        blobContentHashListWithCacheMetadata),
                    CancellationToken.None).ConfigureAwait(false);

                DownloadUriCache.Instance.BulkAddDownloadUris(addResult.BlobDownloadUris);

                // add succeeded but returned an empty contenthashlistwith cache metadata. correct this.
                if (addResult.ContentHashListWithCacheMetadata == null)
                {
                    return
                        (new ObjectResult <ContentHashListWithCacheMetadata>(
                             new ContentHashListWithCacheMetadata(
                                 new ContentHashListWithDeterminism(null, blobContentHashListWithCacheMetadata.Determinism),
                                 blobContentHashListWithCacheMetadata.GetRawExpirationTimeUtc(),
                                 blobContentHashListWithCacheMetadata.ContentGuarantee)));
                }
                else
                {
                    return(await UnpackBlobContentHashListAsync(context, addResult.ContentHashListWithCacheMetadata));
                }
            }
            catch (Exception ex)
            {
                return(new ObjectResult <ContentHashListWithCacheMetadata>(ex));
            }
        }
Beispiel #10
0
 /// <inheritdoc />
 protected override Task <PutResult> PutStreamCoreAsync(OperationContext operationContext, ContentHash contentHash, Stream stream, UrgencyHint urgencyHint, Counter retryCounter)
 {
     return(_innerSession.PutStreamAsync(operationContext, contentHash, stream, operationContext.Token, urgencyHint));
 }