Пример #1
0
        public void GetMonitor_ReturnsSharedMonitor()
        {
            var queueListener           = new QueueListener();
            var watcherMock             = new Mock <IBlobWrittenWatcher>(MockBehavior.Strict);
            var executor                = new BlobQueueTriggerExecutor(watcherMock.Object, NullLogger <BlobListener> .Instance);
            var sharedBlobQueueListener = new SharedBlobQueueListener(queueListener, executor);
            var sharedListenerMock      = new Mock <ISharedListener>(MockBehavior.Strict);
            var blobListener1           = new BlobListener(sharedBlobQueueListener);
            var blobListener2           = new BlobListener(sharedBlobQueueListener);

            var monitor1 = blobListener1.GetMonitor();
            var monitor2 = blobListener1.GetMonitor();

            Assert.AreSame(monitor1, monitor2);
            Assert.AreSame(monitor1, queueListener);
        }
Пример #2
0
        public async Task <IListener> CreateAsync(CancellationToken cancellationToken)
        {
            // Note that these clients are intentionally for the storage account rather than for the dashboard account.
            // We use the storage, not dashboard, account for the blob receipt container and blob trigger queues.
            var primaryBlobClient = _hostBlobServiceClient;

            // Important: We're using the storage account of the function target here, which is the account that the
            // function the listener is for is targeting. This is the account that will be used
            // to read the trigger blob.
            var targetBlobClient  = _dataBlobServiceClient;
            var targetQueueClient = _dataQueueServiceClient;

            BlobTriggerQueueWriter blobTriggerQueueWriter = await _blobTriggerQueueWriterFactory.CreateAsync(cancellationToken).ConfigureAwait(false);

            string hostId = await _hostIdProvider.GetHostIdAsync(cancellationToken).ConfigureAwait(false);

            SharedBlobListener sharedBlobListener = null;

            // we do not need to create SharedBlobListener for EventGrid blob trigger
            if (_blobTriggerSource == BlobTriggerSource.LogsAndContainerScan)
            {
                sharedBlobListener = _sharedContextProvider.GetOrCreateInstance <SharedBlobListener>(
                    new SharedBlobListenerFactory(hostId, _hostBlobServiceClient, _exceptionHandler, _blobWrittenWatcherSetter, _loggerFactory.CreateLogger <BlobListener>()));

                // Register the blob container we wish to monitor with the shared blob listener.
                await RegisterWithSharedBlobListenerAsync(hostId, sharedBlobListener, primaryBlobClient,
                                                          blobTriggerQueueWriter, cancellationToken).ConfigureAwait(false);
            }

            // Create a "bridge" listener that will monitor the blob
            // notification queue and dispatch to the target job function.
            SharedBlobQueueListener sharedBlobQueueListener = _sharedContextProvider.GetOrCreateInstance <SharedBlobQueueListener>(
                new SharedBlobQueueListenerFactory(_hostQueueServiceClient, blobTriggerQueueWriter.SharedQueueWatcher, blobTriggerQueueWriter.QueueClient,
                                                   _blobsOptions, _exceptionHandler, _loggerFactory, sharedBlobListener?.BlobWritterWatcher, _functionDescriptor, _blobTriggerSource, _concurrencyManager));
            var queueListener = new BlobListener(sharedBlobQueueListener);

            // the client to use for the poison queue
            // by default this should target the same storage account
            // as the blob container we're monitoring
            var poisonQueueClient = targetQueueClient;

            // Register our function with the shared blob queue listener
            RegisterWithSharedBlobQueueListenerAsync(sharedBlobQueueListener, targetBlobClient, poisonQueueClient);

            // Check a flag in the shared context to see if we've created the singleton
            // shared blob listener in this host instance.
            // We do not need SharedBlobListener for EventGrid blob trigger.
            object singletonListenerCreated = false;

            if (_blobTriggerSource == BlobTriggerSource.LogsAndContainerScan &&
                !_sharedContextProvider.TryGetValue(SingletonBlobListenerScopeId, out singletonListenerCreated))
            {
                // Create a singleton shared blob listener, since we only
                // want a single instance of the blob poll/scan logic to be running
                // across host instances
                var singletonBlobListener = _singletonManager.CreateHostSingletonListener(
                    new BlobListener(sharedBlobListener), SingletonBlobListenerScopeId);
                _sharedContextProvider.SetValue(SingletonBlobListenerScopeId, true);

                return(new CompositeListener(singletonBlobListener, queueListener));
            }
            else
            {
                // We've already created the singleton blob listener
                // so just return our queue listener. Note that while we want the
                // blob scan to be singleton, the shared queue listener needs to run
                // on ALL instances so load can be scaled out
                return(queueListener);
            }
        }