/// <inheritdoc /> public Task <IEnumerable <Task <Indexed <PinResult> > > > PinAsync(Context context, IReadOnlyList <ContentHash> contentHashes, CancellationToken cts, UrgencyHint urgencyHint = UrgencyHint.Nominal) { if (WriteThroughContentSession != null) { return(Workflows.RunWithFallback( contentHashes, hashes => WriteThroughContentSession.PinAsync(context, hashes, cts, urgencyHint), hashes => BackingContentSession.PinAsync(context, hashes, cts, urgencyHint), result => result.Succeeded)); } return(BackingContentSession.PinAsync(context, contentHashes, cts, urgencyHint)); }
/// <inheritdoc /> public async Task <PinResult> PinAsync( Context context, ContentHash contentHash, CancellationToken cts, UrgencyHint urgencyHint = UrgencyHint.Nominal) { var pinResult = await _sessionForStream.PinAsync(context, contentHash, cts, urgencyHint); if (pinResult.Code == PinResult.ResultCode.ContentNotFound) { pinResult = await _sessionForPath.PinAsync(context, contentHash, cts, urgencyHint); } return(pinResult); }
/// <summary> /// Ensure the existence of all related content by pinning it. /// </summary> public static async Task <bool> EnsureContentIsAvailableAsync(this IContentSession contentSession, Context context, string componentName, ContentHashList contentHashList, CancellationToken cts) { // If there is no contentSession in which to find content, then trivially no content is available. if (contentSession == null) { return(false); } // If the contentHashList does not exist, then trivially all content is pinned. if (contentHashList == null) { return(true); } IEnumerable <Task <Indexed <PinResult> > > pinResultEnumerable = await contentSession.PinAsync(context, contentHashList.Hashes, cts).ConfigureAwait(false); var pinSucceeded = true; foreach (var pinResultTask in pinResultEnumerable) { var pinResult = await pinResultTask.ConfigureAwait(false); if (!pinResult.Item.Succeeded) { if (pinResult.Item.Code != PinResult.ResultCode.ContentNotFound) { context.Warning($"Pinning hash {contentHashList.Hashes[pinResult.Index]} failed with error {pinResult}", component: componentName); } pinSucceeded = false; } } return(pinSucceeded); }
private async Task <BoolResult> PushToRemoteAsync(OperationContext context, IReadOnlyList <ContentHash> hashes) { Contract.Check(_publisher != null)?.Assert("Startup should be run before attempting to publish."); var pinResults = await Task.WhenAll(await _sourceContentSession.PinAsync(context, hashes, context.Token)); var missingFromLocal = pinResults.Where(r => !r.Item.Succeeded); if (missingFromLocal.Any()) { return(new BoolResult($"Not all contents of the content hash list are available in the cache. Missing hashes: {string.Join(", ", missingFromLocal.Select(m => hashes[m.Index].ToShortString()))}")); } // TODO: concurrency? foreach (var hash in hashes) { var streamResult = await _sourceContentSession.OpenStreamAsync(context, hash, context.Token).ThrowIfFailure(); var stream = streamResult.Stream; var putStreamResult = await _publisher.PutStreamAsync(context, hash, stream, context.Token).ThrowIfFailure(); } return(BoolResult.Success); }
public async Task MultipleClients() { 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; IContentSession session2 = null; try { var createSessionResult1 = store.CreateSession(_context, "session1", ImplicitPin.None); createSessionResult1.ShouldBeSuccess(); var createSessionResult2 = store.CreateSession(_context, "session2", ImplicitPin.None); createSessionResult2.ShouldBeSuccess(); using (createSessionResult1.Session) using (createSessionResult2.Session) { var r1 = await createSessionResult1.Session.StartupAsync(_context); r1.ShouldBeSuccess(); session1 = createSessionResult1.Session; var startupSessionResult2 = await createSessionResult2.Session.StartupAsync(_context); startupSessionResult2.ShouldBeSuccess(); session2 = createSessionResult2.Session; var putResult = await session1.PutRandomAsync( _context, ContentHashType, false, RandomContentByteCount, Token); var tasks1 = Enumerable.Range(0, (int)ConnectionsPerSession) .Select(_ => Task.Run(async() => await session1.PinAsync(_context, putResult.ContentHash, Token))) .ToList(); var tasks2 = Enumerable.Range(0, (int)ConnectionsPerSession) .Select(_ => Task.Run(async() => await session2.PinAsync(_context, putResult.ContentHash, Token))) .ToList(); foreach (var task in tasks1.Union(tasks2)) { var result = await task; result.ShouldBeSuccess(); } } } finally { if (session2 != null) { await session2.ShutdownAsync(_context).ShouldBeSuccess(); } if (session1 != null) { await session1.ShutdownAsync(_context).ShouldBeSuccess(); } } } finally { var r = await store.ShutdownAsync(_context); r.ShouldBeSuccess(); } } } }
public async Task MultipleCaches() { const string CacheName1 = "test1"; const string CacheName2 = "test2"; using (var testDirectory0 = new DisposableDirectory(FileSystem)) using (var testDirectory1 = new DisposableDirectory(FileSystem)) using (var testDirectory2 = new DisposableDirectory(FileSystem)) { var config = CreateStoreConfiguration(); var rootPath1 = testDirectory1.Path; config.Write(FileSystem, rootPath1); var rootPath2 = testDirectory2.Path; config.Write(FileSystem, rootPath2); var grpcPort = PortExtensions.GetNextAvailablePort(); var grpcPortFileName = Guid.NewGuid().ToString(); var serviceConfiguration = new ServiceConfiguration( new Dictionary <string, AbsolutePath> { { CacheName1, rootPath1 }, { CacheName2, rootPath2 } }, testDirectory0.Path, ServiceConfiguration.DefaultGracefulShutdownSeconds, grpcPort, grpcPortFileName); using (var server = CreateServer(serviceConfiguration)) { var factory = new MemoryMappedFileGrpcPortSharingFactory(Logger, grpcPortFileName); var reader = factory.GetPortReader(); var port = reader.ReadPort(); var rpcConfig = new ServiceClientRpcConfiguration(port); using (var store1 = new ServiceClientContentStore( Logger, FileSystem, new ServiceClientContentStoreConfiguration(CacheName1, rpcConfig, Scenario))) using (var store2 = new ServiceClientContentStore( Logger, FileSystem, new ServiceClientContentStoreConfiguration(CacheName2, rpcConfig, Scenario))) { try { var rs = await server.StartupAsync(_context); rs.ShouldBeSuccess(); var storeBoolResult1 = await store1.StartupAsync(_context); storeBoolResult1.ShouldBeSuccess(); var storeBoolResult2 = await store2.StartupAsync(_context); storeBoolResult2.ShouldBeSuccess(); IContentSession session1 = null; IContentSession session2 = null; try { var createSessionResult1 = store1.CreateSession(_context, "session1", ImplicitPin.None); createSessionResult1.ShouldBeSuccess(); var createSessionResult2 = store2.CreateSession(_context, "session2", ImplicitPin.None); createSessionResult2.ShouldBeSuccess(); using (createSessionResult1.Session) using (createSessionResult2.Session) { var r1 = await createSessionResult1.Session.StartupAsync(_context); r1.ShouldBeSuccess(); session1 = createSessionResult1.Session; var r2 = await createSessionResult2.Session.StartupAsync(_context); r2.ShouldBeSuccess(); session2 = createSessionResult2.Session; var r3 = await session1.PutRandomAsync( _context, ContentHashType, false, RandomContentByteCount, Token); var pinResult = await session1.PinAsync(_context, r3.ContentHash, Token); pinResult.ShouldBeSuccess(); r3 = await session2.PutRandomAsync( _context, ContentHashType, false, RandomContentByteCount, Token); pinResult = await session2.PinAsync(_context, r3.ContentHash, Token); pinResult.ShouldBeSuccess(); } } finally { if (session2 != null) { await session2.ShutdownAsync(_context).ShouldBeSuccess(); } if (session1 != null) { await session1.ShutdownAsync(_context).ShouldBeSuccess(); } } } finally { BoolResult r1 = null; BoolResult r2 = null; if (store1.StartupCompleted) { r1 = await store1.ShutdownAsync(_context); } if (store2.StartupCompleted) { r2 = await store2.ShutdownAsync(_context); } var r3 = await server.ShutdownAsync(_context); r1?.ShouldBeSuccess(); r2?.ShouldBeSuccess(); r3?.ShouldBeSuccess(); } } } } }
/// <inheritdoc /> protected override Task <PinResult> PinCoreAsync(OperationContext operationContext, ContentHash contentHash, UrgencyHint urgencyHint, Counter retryCounter) { return(_innerSession.PinAsync(operationContext, contentHash, operationContext.Token, urgencyHint)); }