private async Task NotifyRegistrationsAsync(BlobWithContainer <BlobBaseClient> blob, ICollection <BlobWithContainer <BlobBaseClient> > failedNotifications, CancellationToken cancellationToken) { // Blob written notifications are host-wide, so filter out things that aren't in the container list. if (!_registrations.ContainsKey(blob.BlobContainerClient)) { return; } foreach (ITriggerExecutor <BlobTriggerExecutorContext> registration in _registrations[blob.BlobContainerClient]) { cancellationToken.ThrowIfCancellationRequested(); BlobTriggerExecutorContext context = new BlobTriggerExecutorContext { Blob = blob, PollId = null, TriggerSource = BlobTriggerSource.ContainerScan }; FunctionResult result = await registration.ExecuteAsync(context, cancellationToken).ConfigureAwait(false); if (!result.Succeeded) { // If notification failed, try again on the next iteration. failedNotifications.Add(blob); } } }
public static async Task <NotifyingBlobStream> BindStreamAsync(BlobWithContainer <BlobBaseClient> blob, ValueBindingContext context, IBlobWrittenWatcher blobWrittenWatcher) { var blockBlob = blob.BlobClient as BlockBlobClient; if (blockBlob == null) { throw new InvalidOperationException("Cannot bind to page or append blobs using 'out string', 'TextWriter', or writable 'Stream' parameters."); } var functionID = context.FunctionInstanceId; BlobProperties properties = await blockBlob.FetchPropertiesOrNullIfNotExistAsync().ConfigureAwait(false); Dictionary <string, string> metadata = new Dictionary <string, string>(); if (properties != null && properties.Metadata != null) { metadata = new Dictionary <string, string>(properties.Metadata); } BlobCausalityManager.SetWriter(metadata, functionID); BlockBlobOpenWriteOptions options = new BlockBlobOpenWriteOptions() { Metadata = metadata, }; Stream rawStream = await blockBlob.OpenWriteAsync(true, options).ConfigureAwait(false); IBlobCommitedAction committedAction = new BlobCommittedAction(blob, blobWrittenWatcher); return(await Task.FromResult(new NotifyingBlobStream(rawStream, committedAction)).ConfigureAwait(false)); }
/// <summary> /// </summary> /// <param name="blob">Blob for this object in storage.</param> /// <param name="cacheObject">Describes the shared memory region containing this object.</param> /// <param name="blobStream">Stream to use for writing this object to storage.</param> /// <param name="functionDataCache">Cache in which to put this object when required.</param> public CacheableWriteBlob(BlobWithContainer <BlobBaseClient> blob, SharedMemoryMetadata cacheObject, Stream blobStream, IFunctionDataCache functionDataCache) { BlobStream = blobStream; _cacheObject = cacheObject; _functionDataCache = functionDataCache; _blob = blob; }
public static async Task <ICacheAwareWriteObject> BindStreamCacheAwareAsync(BlobWithContainer <BlobBaseClient> blob, ValueBindingContext context, IBlobWrittenWatcher blobWrittenWatcher, IFunctionDataCache functionDataCache) { Stream blobStream = await BindStreamAsync(blob, context, blobWrittenWatcher).ConfigureAwait(false); return(new CacheableWriteBlob(blob, context.SharedMemoryMetadata, blobStream, functionDataCache)); }
private async Task NotifyRegistrationsAsync(BlobWithContainer <BlobBaseClient> blob, string pollId, CancellationToken cancellationToken) { // Log listening is client-wide and blob written notifications are host-wide, so filter out things that // aren't in the container list. if (!_registrations.ContainsKey(blob.BlobContainerClient)) { return; } foreach (ITriggerExecutor <BlobTriggerExecutorContext> registration in _registrations[blob.BlobContainerClient]) { cancellationToken.ThrowIfCancellationRequested(); BlobTriggerExecutorContext context = new BlobTriggerExecutorContext { Blob = blob, PollId = pollId, TriggerSource = BlobTriggerSource.LogScan }; FunctionResult result = await registration.ExecuteAsync(context, cancellationToken).ConfigureAwait(false); if (!result.Succeeded) { // If notification failed, try again on the next iteration. BlobNotification notification = new BlobNotification(blob, pollId); _blobsFoundFromScanOrNotification.Enqueue(notification); } } }
public async Task TryPutToCache_VerifyResultMatchesResultOfCacheOperation(bool expected) { // Arrange Mock <SharedMemoryMetadata> sharedMemMetaMock = CreateMockSharedMemoryMetadata(); SharedMemoryMetadata sharedMemMeta = sharedMemMetaMock.Object; bool isIncrementActiveRefs = false; bool isDeleteOnFailure = false; Mock <IFunctionDataCache> cacheMock = CreateMockFunctionDataCache(); cacheMock .Setup(c => c.TryPut(It.IsAny <FunctionDataCacheKey>(), sharedMemMeta, isIncrementActiveRefs, isDeleteOnFailure)) .Returns(expected) .Verifiable(); IFunctionDataCache cache = cacheMock.Object; BlobWithContainer <BlobBaseClient> blob = CreateBlobReference(ContainerName, "blob"); Mock <Stream> mockBlobStream = CreateMockBlobStream(); Stream blobStream = mockBlobStream.Object; CacheableWriteBlob cacheableWriteBlob = CreateProductUnderTest(blob, sharedMemMeta, blobStream, cache); // Act bool result = await cacheableWriteBlob.TryPutToCacheAsync(isDeleteOnFailure); // Assert Assert.AreEqual(expected, result); cacheMock.Verify(); }
public async Task TryPutToCache_CacheObjectNull_VerifyFailure() { // Arrange bool isIncrementActiveRefs = false; bool isDeleteOnFailure = false; Mock <IFunctionDataCache> cacheMock = CreateMockFunctionDataCache(); cacheMock .Setup(c => c.TryPut(It.IsAny <FunctionDataCacheKey>(), It.IsAny <SharedMemoryMetadata>(), isIncrementActiveRefs, isDeleteOnFailure)) .Throws(new Exception("This should not be called")); IFunctionDataCache cache = cacheMock.Object; BlobWithContainer <BlobBaseClient> blob = CreateBlobReference(ContainerName, "blob"); Mock <Stream> mockBlobStream = CreateMockBlobStream(); Stream blobStream = mockBlobStream.Object; CacheableWriteBlob cacheableWriteBlob = CreateProductUnderTest(blob, null, blobStream, cache); // Act bool result = await cacheableWriteBlob.TryPutToCacheAsync(isDeleteOnFailure); // Assert Assert.IsFalse(result); }
public void Notify(BlobWithContainer <BlobBaseClient> blobWritten) { _blobWrittenNotifications.Enqueue(blobWritten); }
private static IBlobPathSource CreateBlobPath(BlobWithContainer <BlobBaseClient> blob) { return(new FixedBlobPathSource(blob.BlobClient.ToBlobPath())); }
public void Notify(BlobWithContainer <BlobBaseClient> blobWritten) { ThrowIfDisposed(); _blobsFoundFromScanOrNotification.Enqueue(new BlobNotification(blobWritten, null)); }
public BlobNotification(BlobWithContainer <BlobBaseClient> blob, string originalClientRequestId) { Blob = blob; PollId = originalClientRequestId; }
/// <summary> /// Create a <see cref="CacheableWriteBlob"/> to use for a test. /// </summary> /// <param name="blob">Blob for this object in storage.</param> /// <param name="cacheObject">Describes the shared memory region containing this object.</param> /// <param name="blobStream">Stream to use for writing this object to storage.</param> /// <param name="functionDataCache">Cache in which to put this object when required.</param> /// <returns>A <see cref="CacheableWriteBlob"/> object to use for a test.</returns> private static CacheableWriteBlob CreateProductUnderTest(BlobWithContainer <BlobBaseClient> blob, SharedMemoryMetadata cacheObject, Stream blobStream, IFunctionDataCache functionDataCache) { return(new CacheableWriteBlob(blob, cacheObject, blobStream, functionDataCache)); }
public BlobCommittedAction(BlobWithContainer <BlobBaseClient> blob, IBlobWrittenWatcher blobWrittenWatcher) { _blob = blob; _blobWrittenWatcher = blobWrittenWatcher; }