public SharedBlobListener(IStorageAccount storageAccount,
     IBackgroundExceptionDispatcher backgroundExceptionDispatcher)
 {
     _strategy = CreateStrategy(storageAccount);
     // Start the first iteration immediately.
     _timer = new TaskSeriesTimer(_strategy, backgroundExceptionDispatcher, initialWait: Task.Delay(0));
 }
Esempio n. 2
0
        public void Dispose_IfStarted_DoesNotWaitForExecuteToFinish()
        {
            // Arrange
            using (EventWaitHandle executeStarted = new ManualResetEvent(initialState: false))
                using (EventWaitHandle stopExecute = new ManualResetEvent(initialState: false))
                {
                    bool waitedForCommandToFinish = false;

                    ITaskSeriesCommand command = CreateCommand(() =>
                    {
                        Assert.True(executeStarted.Set()); // Guard
                        stopExecute.WaitOne(1000);
                        waitedForCommandToFinish = true;
                        return(new TaskSeriesCommandResult(wait: Task.Delay(0)));
                    });

                    using (ITaskSeriesTimer product = CreateProductUnderTest(command))
                    {
                        product.Start();
                        Assert.True(executeStarted.WaitOne(1000)); // Guard

                        // Act & Assert
                        product.Dispose();

                        // Assert
                        Assert.False(waitedForCommandToFinish);

                        // Cleanup
                        Assert.True(stopExecute.Set()); // Guard
                    }
                }
        }
Esempio n. 3
0
        public void Start_AfterInitialWait_Executes()
        {
            // Arrange
            // Detect the difference between waiting and not waiting, but keep the test execution time fast.
            TimeSpan initialDelay = TimeSpan.FromMilliseconds(50);

            using (EventWaitHandle executedWaitHandle = new ManualResetEvent(initialState: false))
            {
                ITaskSeriesCommand command = CreateCommand(() =>
                {
                    Assert.True(executedWaitHandle.Set()); // Guard
                    return(new TaskSeriesCommandResult(wait: Task.Delay(TimeSpan.FromDays(1))));
                });

                using (ITaskSeriesTimer product = CreateProductUnderTest(command, Task.Delay(initialDelay)))
                {
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();

                    // Act
                    product.Start();

                    // Assert
                    Assert.True(executedWaitHandle.WaitOne(1000)); // Guard
                    stopwatch.Stop();
                    // Account for the resolution of the system timer; otherwise, the test may fail intermittently
                    // (as the timer may fire slightly before the precise expected value).
                    TimeSpan effectiveActualDelay = AddSystemTimerResolution(stopwatch.Elapsed);
                    AssertGreaterThan(initialDelay, effectiveActualDelay);
                }
            }
        }
Esempio n. 4
0
 public HeartbeatListener(IRecurrentCommand heartbeatCommand,
                          IWebJobsExceptionHandler exceptionHandler, IListener innerListener)
 {
     _heartbeatCommand = heartbeatCommand;
     _innerListener    = innerListener;
     _timer            = CreateTimer(exceptionHandler);
 }
Esempio n. 5
0
 public SharedBlobListener(string hostId, StorageAccount storageAccount,
                           IWebJobsExceptionHandler exceptionHandler)
 {
     _strategy = CreateStrategy(hostId, storageAccount);
     // Start the first iteration immediately.
     _timer = new TaskSeriesTimer(_strategy, exceptionHandler, initialWait: Task.Delay(0));
 }
Esempio n. 6
0
        public void StopAsync_TriggersCommandCancellationToken()
        {
            // Arrange
            using (EventWaitHandle executeStarted = new ManualResetEvent(initialState: false))
                using (EventWaitHandle executeFinished = new ManualResetEvent(initialState: false))
                {
                    bool cancellationTokenSignalled = false;

                    ITaskSeriesCommand command = CreateCommand((cancellationToken) =>
                    {
                        Assert.True(executeStarted.Set());  // Guard
                        cancellationTokenSignalled = cancellationToken.WaitHandle.WaitOne(1000);
                        Assert.True(executeFinished.Set()); // Guard
                        return(new TaskSeriesCommandResult(wait: Task.Delay(0)));
                    });

                    using (ITaskSeriesTimer product = CreateProductUnderTest(command))
                    {
                        product.Start();
                        Assert.True(executeStarted.WaitOne(1000)); // Guard

                        CancellationToken cancellationToken = CancellationToken.None;

                        // Act
                        Task task = product.StopAsync(cancellationToken);

                        // Assert
                        Assert.NotNull(task);
                        task.GetAwaiter().GetResult();
                        Assert.True(executeFinished.WaitOne(1000)); // Guard
                        Assert.True(cancellationTokenSignalled);
                    }
                }
        }
 public SharedBlobListener(IStorageAccount storageAccount,
                           IBackgroundExceptionDispatcher backgroundExceptionDispatcher)
 {
     _strategy = CreateStrategy(storageAccount);
     // Start the first iteration immediately.
     _timer = new TaskSeriesTimer(_strategy, backgroundExceptionDispatcher, initialWait: Task.Delay(0));
 }
Esempio n. 8
0
        public void StopAsync_WhenCanceled_DoesNotWaitForExecuteToFinishToCompleteTask()
        {
            // Arrange
            using (EventWaitHandle executeStarted = new ManualResetEvent(initialState: false))
            {
                ITaskSeriesCommand command = CreateCommand(() =>
                {
                    Assert.True(executeStarted.Set()); // Guard
                    return(new TaskSeriesCommandResult(wait: Task.Delay(2000)));
                });

                using (ITaskSeriesTimer product = CreateProductUnderTest(command))
                {
                    product.Start();
                    Assert.True(executeStarted.WaitOne(1000)); // Guard

                    CancellationToken cancellationToken = new CancellationToken(canceled: true);

                    // Act
                    Task task = product.StopAsync(cancellationToken);

                    // Assert
                    Assert.NotNull(task);
                    Assert.True(task.WaitUntilCompleted(1000));
                    Assert.True(task.IsCompleted);
                }
            }
        }
        internal async Task ProcessMessageAsync(IStorageQueueMessage message, TimeSpan visibilityTimeout, CancellationToken cancellationToken)
        {
            try
            {
                if (!await _queueProcessor.BeginProcessingMessageAsync(message.SdkObject, cancellationToken))
                {
                    return;
                }

                FunctionResult result = null;
                using (ITaskSeriesTimer timer = CreateUpdateMessageVisibilityTimer(_queue, message, visibilityTimeout, _backgroundExceptionDispatcher))
                {
                    timer.Start();

                    result = await _triggerExecutor.ExecuteAsync(message, cancellationToken);

                    await timer.StopAsync(cancellationToken);
                }

                await _queueProcessor.CompleteProcessingMessageAsync(message.SdkObject, result, cancellationToken);
            }
            catch (OperationCanceledException)
            {
                // Don't fail the top-level task when an inner task cancels.
            }
            catch (Exception exception)
            {
                // Immediately report any unhandled exception from this background task.
                // (Don't capture the exception as a fault of this Task; that would delay any exception reporting until
                // Stop is called, which might never happen.)
                _backgroundExceptionDispatcher.Throw(ExceptionDispatchInfo.Capture(exception));
            }
        }
 public HeartbeatListener(IRecurrentCommand heartbeatCommand,
                          IBackgroundExceptionDispatcher backgroundExceptionDispatcher, IListener innerListener)
 {
     _heartbeatCommand = heartbeatCommand;
     _innerListener    = innerListener;
     _timer            = CreateTimer(backgroundExceptionDispatcher);
 }
 public HeartbeatListener(IRecurrentCommand heartbeatCommand,
     IBackgroundExceptionDispatcher backgroundExceptionDispatcher, IListener innerListener)
 {
     _heartbeatCommand = heartbeatCommand;
     _innerListener = innerListener;
     _timer = CreateTimer(backgroundExceptionDispatcher);
 }
Esempio n. 12
0
        public void StopAsync_DoesNotWaitForSubsequentWaitToCompleteTask()
        {
            // Arrange
            using (EventWaitHandle executeStarted = new ManualResetEvent(initialState: false))
            {
                ITaskSeriesCommand command = CreateCommand(() =>
                {
                    Assert.True(executeStarted.Set()); // Guard
                    return(new TaskSeriesCommandResult(wait: Task.Delay(2000)));
                });

                using (ITaskSeriesTimer product = CreateProductUnderTest(command))
                {
                    product.Start();
                    Assert.True(executeStarted.WaitOne(1000)); // Guard

                    // Wait for the background thread to enter the long wait.
                    Thread.Sleep(5);

                    CancellationToken cancellationToken = CancellationToken.None;

                    // Act
                    Task task = product.StopAsync(cancellationToken);

                    // Assert
                    Assert.NotNull(task);
                    Assert.True(task.WaitUntilCompleted(1000));
                    Assert.True(task.IsCompleted);
                }
            }
        }
Esempio n. 13
0
        private async Task ExecuteWithOutputLogsAsync(IFunctionInstance instance,
                                                      IReadOnlyDictionary <string, IValueProvider> parameters,
                                                      TextWriter consoleOutput,
                                                      IFunctionOutputDefinition outputDefinition,
                                                      IDictionary <string, ParameterLog> parameterLogCollector,
                                                      CancellationToken cancellationToken)
        {
            IFunctionInvoker invoker = instance.Invoker;
            IReadOnlyDictionary <string, IWatcher> watches = CreateWatches(parameters);
            IRecurrentCommand updateParameterLogCommand    =
                outputDefinition.CreateParameterLogUpdateCommand(watches, consoleOutput);

            using (ITaskSeriesTimer updateParameterLogTimer = StartParameterLogTimer(updateParameterLogCommand,
                                                                                     _backgroundExceptionDispatcher))
            {
                try
                {
                    await ExecuteWithWatchersAsync(invoker, parameters, cancellationToken);

                    if (updateParameterLogTimer != null)
                    {
                        // Stop the watches after calling IValueBinder.SetValue (it may do things that should show up in
                        // the watches).
                        // Also, IValueBinder.SetValue could also take a long time (flushing large caches), and so it's
                        // useful to have watches still running.
                        await updateParameterLogTimer.StopAsync(cancellationToken);
                    }
                }
                finally
                {
                    ValueWatcher.AddLogs(watches, parameterLogCollector);
                }
            }
        }
Esempio n. 14
0
        public void Dispose_TriggersCommandCancellationToken()
        {
            // Arrange
            TimeSpan interval = TimeSpan.Zero;

            using (EventWaitHandle executeStarted = new ManualResetEvent(initialState: false))
                using (EventWaitHandle executeFinished = new ManualResetEvent(initialState: false))
                {
                    bool cancellationTokenSignalled = false;

                    ITaskSeriesCommand command = CreateCommand((cancellationToken) =>
                    {
                        Assert.True(executeStarted.Set());  // Guard
                        cancellationTokenSignalled = cancellationToken.WaitHandle.WaitOne(1000);
                        Assert.True(executeFinished.Set()); // Guard
                        return(new TaskSeriesCommandResult(wait: Task.Delay(0)));
                    });

                    using (ITaskSeriesTimer product = CreateProductUnderTest(command))
                    {
                        product.Start();
                        Assert.True(executeStarted.WaitOne(1000)); // Guard

                        // Act
                        product.Dispose();

                        // Assert
                        Assert.True(executeFinished.WaitOne(1000)); // Guard
                        Assert.True(cancellationTokenSignalled);
                    }
                }
        }
Esempio n. 15
0
        public QueueListener(IStorageQueue queue,
                             IStorageQueue poisonQueue,
                             ITriggerExecutor <IStorageQueueMessage> triggerExecutor,
                             IWebJobsExceptionHandler exceptionHandler,
                             ILoggerFactory loggerFactory,
                             SharedQueueWatcher sharedWatcher,
                             IQueueConfiguration queueConfiguration,
                             QueueProcessor queueProcessor = null,
                             TimeSpan?maxPollingInterval   = null)
        {
            if (queueConfiguration == null)
            {
                throw new ArgumentNullException("queueConfiguration");
            }

            if (queueConfiguration.BatchSize <= 0)
            {
                throw new ArgumentException("BatchSize must be greater than zero.");
            }

            if (queueConfiguration.MaxDequeueCount <= 0)
            {
                throw new ArgumentException("MaxDequeueCount must be greater than zero.");
            }

            _timer              = new TaskSeriesTimer(this, exceptionHandler, Task.Delay(0));
            _queue              = queue;
            _poisonQueue        = poisonQueue;
            _triggerExecutor    = triggerExecutor;
            _exceptionHandler   = exceptionHandler;
            _queueConfiguration = queueConfiguration;

            // if the function runs longer than this, the invisibility will be updated
            // on a timer periodically for the duration of the function execution
            _visibilityTimeout = TimeSpan.FromMinutes(10);

            if (sharedWatcher != null)
            {
                // Call Notify whenever a function adds a message to this queue.
                sharedWatcher.Register(queue.Name, this);
                _sharedWatcher = sharedWatcher;
            }

            EventHandler <PoisonMessageEventArgs> poisonMessageEventHandler = _sharedWatcher != null ? OnMessageAddedToPoisonQueue : (EventHandler <PoisonMessageEventArgs>)null;

            _queueProcessor = queueProcessor ?? CreateQueueProcessor(
                _queue.SdkObject, _poisonQueue != null ? _poisonQueue.SdkObject : null,
                loggerFactory, _queueConfiguration, poisonMessageEventHandler);

            TimeSpan maximumInterval = _queueProcessor.MaxPollingInterval;

            if (maxPollingInterval.HasValue && maximumInterval > maxPollingInterval.Value)
            {
                // enforce the maximum polling interval if specified
                maximumInterval = maxPollingInterval.Value;
            }

            _delayStrategy = new RandomizedExponentialBackoffStrategy(QueuePollingIntervals.Minimum, maximumInterval);
        }
 // Begin watchers.
 public ValueWatcher(IReadOnlyDictionary<string, IWatcher> watches, CloudBlockBlob blobResults,
     TextWriter consoleOutput, IBackgroundExceptionDispatcher backgroundExceptionDispatcher)
 {
     ValueWatcherCommand command = new ValueWatcherCommand(watches, blobResults, consoleOutput);
     _command = command;
     _timer = ValueWatcherCommand.CreateTimer(command, backgroundExceptionDispatcher);
     _timer.Start();
 }
    public static RenewableLockHandle CreateRenewableLockHandle(TimeSpan leasePeriod,
                                                                IDistributedLockManager distributedLockManager, IDistributedLock lockHandle, Func <bool> preExecuteCheck)
    {
        ITaskSeriesTimer renewal =
            CreateLeaseRenewalTimer(leasePeriod, distributedLockManager, lockHandle, preExecuteCheck);

        renewal.Start();
        return(new RenewableLockHandle(lockHandle, renewal));
    }
        // Begin watchers.
        public ValueWatcher(IReadOnlyDictionary <string, IWatcher> watches, CloudBlockBlob blobResults,
                            TextWriter consoleOutput, IBackgroundExceptionDispatcher backgroundExceptionDispatcher)
        {
            ValueWatcherCommand command = new ValueWatcherCommand(watches, blobResults, consoleOutput);

            _command = command;
            _timer   = ValueWatcherCommand.CreateTimer(command, backgroundExceptionDispatcher);
            _timer.Start();
        }
Esempio n. 19
0
        public void Dispose_IfNotStarted_DoesNotThrow()
        {
            // Arrange
            ITaskSeriesCommand command = CreateDummyCommand();
            ITaskSeriesTimer   product = CreateProductUnderTest(command);

            // Act & Assert
            ExceptionAssert.DoesNotThrow(() => product.Dispose());
        }
Esempio n. 20
0
        private async Task ProcessMessageAsync(IStorageQueueMessage message, TimeSpan visibilityTimeout,
                                               CancellationToken cancellationToken)
        {
            try
            {
                bool succeeded;

                using (ITaskSeriesTimer timer = CreateUpdateMessageVisibilityTimer(_queue, message, visibilityTimeout,
                                                                                   _backgroundExceptionDispatcher))
                {
                    timer.Start();

                    succeeded = await _triggerExecutor.ExecuteAsync(message, cancellationToken);

                    await timer.StopAsync(cancellationToken);
                }

                // Need to call Delete message only if function succeeded.
                if (succeeded)
                {
                    await DeleteMessageAsync(message, cancellationToken);
                }
                else if (_poisonQueue != null)
                {
                    if (message.DequeueCount >= _maxDequeueCount)
                    {
                        _log.WriteLine("Message has reached MaxDequeueCount of {0}. Moving message to queue '{1}'.",
                                       _maxDequeueCount,
                                       _poisonQueue.Name);
                        await CopyToPoisonQueueAsync(message, cancellationToken);
                        await DeleteMessageAsync(message, cancellationToken);
                    }
                    else
                    {
                        await ReleaseMessageAsync(message, cancellationToken);
                    }
                }
                else
                {
                    // For queues without a corresponding poison queue, leave the message invisible when processing
                    // fails to prevent a fast infinite loop.
                    // Specifically, don't call ReleaseMessage(message)
                }
            }
            catch (OperationCanceledException)
            {
                // Don't fail the top-level task when an inner task cancels.
            }
            catch (Exception exception)
            {
                // Immediately report any unhandled exception from this background task.
                // (Don't capture the exception as a fault of this Task; that would delay any exception reporting until
                // Stop is called, which might never happen.)
                _backgroundExceptionDispatcher.Throw(ExceptionDispatchInfo.Capture(exception));
            }
        }
Esempio n. 21
0
        public void Cancel_IfDisposed_Throws()
        {
            // Arrange
            ITaskSeriesCommand command = CreateDummyCommand();
            ITaskSeriesTimer   product = CreateProductUnderTest(command);

            product.Dispose();

            // Act & Assert
            ExceptionAssert.ThrowsObjectDisposed(() => product.Cancel());
        }
Esempio n. 22
0
        public void Dispose_IfStopped_DoesNotThrow()
        {
            // Arrange
            ITaskSeriesCommand command = CreateStubCommand(TimeSpan.Zero);
            ITaskSeriesTimer   product = CreateProductUnderTest(command);

            product.Start();
            product.StopAsync(CancellationToken.None).GetAwaiter().GetResult();

            // Act & Assert
            ExceptionAssert.DoesNotThrow(() => product.Dispose());
        }
Esempio n. 23
0
        public void StopAsync_IfDisposed_Throws()
        {
            // Arrange
            ITaskSeriesCommand command = CreateDummyCommand();
            ITaskSeriesTimer   product = CreateProductUnderTest(command);

            product.Dispose();

            CancellationToken cancellationToken = CancellationToken.None;

            // Act & Assert
            ExceptionAssert.ThrowsObjectDisposed(() => product.StopAsync(cancellationToken));
        }
        public QueueListener(IStorageQueue queue,
                             IStorageQueue poisonQueue,
                             ITriggerExecutor <IStorageQueueMessage> triggerExecutor,
                             IDelayStrategy delayStrategy,
                             IBackgroundExceptionDispatcher backgroundExceptionDispatcher,
                             TraceWriter trace,
                             SharedQueueWatcher sharedWatcher,
                             IQueueConfiguration queueConfiguration)
        {
            if (trace == null)
            {
                throw new ArgumentNullException("trace");
            }

            if (queueConfiguration == null)
            {
                throw new ArgumentNullException("queueConfiguration");
            }

            if (queueConfiguration.BatchSize <= 0)
            {
                throw new ArgumentException("BatchSize must be greater than zero.");
            }

            if (queueConfiguration.MaxDequeueCount <= 0)
            {
                throw new ArgumentException("MaxDequeueCount must be greater than zero.");
            }

            _timer           = new TaskSeriesTimer(this, backgroundExceptionDispatcher, Task.Delay(0));
            _queue           = queue;
            _poisonQueue     = poisonQueue;
            _triggerExecutor = triggerExecutor;
            _delayStrategy   = delayStrategy;
            _backgroundExceptionDispatcher = backgroundExceptionDispatcher;
            _trace = trace;
            _queueConfiguration = queueConfiguration;

            if (sharedWatcher != null)
            {
                // Call Notify whenever a function adds a message to this queue.
                sharedWatcher.Register(queue.Name, this);
                _sharedWatcher = sharedWatcher;
            }

            EventHandler poisonMessageEventHandler = _sharedWatcher != null ? OnMessageAddedToPoisonQueue : (EventHandler)null;

            _queueProcessor = CreateQueueProcessor(
                _queue.SdkObject, _poisonQueue != null ? _poisonQueue.SdkObject : null,
                _trace, _queueConfiguration, poisonMessageEventHandler);
        }
Esempio n. 25
0
        public void StopAsync_IfNotStarted_Throws()
        {
            // Arrange
            ITaskSeriesCommand command = CreateDummyCommand();

            using (ITaskSeriesTimer product = CreateProductUnderTest(command))
            {
                CancellationToken cancellationToken = CancellationToken.None;

                // Act & Assert
                ExceptionAssert.ThrowsInvalidOperation(() => product.StopAsync(cancellationToken),
                                                       "The timer has not yet been started.");
            }
        }
        public QueueListener(IStorageQueue queue,
            IStorageQueue poisonQueue,
            ITriggerExecutor<IStorageQueueMessage> triggerExecutor,
            IDelayStrategy delayStrategy,
            IBackgroundExceptionDispatcher backgroundExceptionDispatcher,
            TraceWriter trace,
            SharedQueueWatcher sharedWatcher,
            IQueueConfiguration queueConfiguration)
        {
            if (trace == null)
            {
                throw new ArgumentNullException("trace");
            }

            if (queueConfiguration == null)
            {
                throw new ArgumentNullException("queueConfiguration");
            }

            if (queueConfiguration.BatchSize <= 0)
            {
                throw new ArgumentException("BatchSize must be greater than zero.");
            }

            if (queueConfiguration.MaxDequeueCount <= 0)
            {
                throw new ArgumentException("MaxDequeueCount must be greater than zero.");
            }

            _timer = new TaskSeriesTimer(this, backgroundExceptionDispatcher, Task.Delay(0));
            _queue = queue;
            _poisonQueue = poisonQueue;
            _triggerExecutor = triggerExecutor;
            _delayStrategy = delayStrategy;
            _backgroundExceptionDispatcher = backgroundExceptionDispatcher;
            _trace = trace;
            _queueConfiguration = queueConfiguration;

            if (sharedWatcher != null)
            {
                // Call Notify whenever a function adds a message to this queue.
                sharedWatcher.Register(queue.Name, this);
                _sharedWatcher = sharedWatcher;
            }

            EventHandler poisonMessageEventHandler = _sharedWatcher != null ? OnMessageAddedToPoisonQueue : (EventHandler)null;
            _queueProcessor = CreateQueueProcessor(
                _queue.SdkObject, _poisonQueue != null ? _poisonQueue.SdkObject : null,
                _trace, _queueConfiguration, poisonMessageEventHandler);
        }
Esempio n. 27
0
        public void Start_IfStarted_Throws()
        {
            // Arrange
            ITaskSeriesCommand command = CreateStubCommand(TimeSpan.FromDays(1));

            using (ITaskSeriesTimer product = CreateProductUnderTest(command))
            {
                product.Start();

                // Act & Assert
                ExceptionAssert.ThrowsInvalidOperation(() => product.Start(),
                                                       "The timer has already been started; it cannot be restarted.");
            }
        }
        private static ITaskSeriesTimer StartOutputTimer(IRecurrentCommand updateCommand, IBackgroundExceptionDispatcher backgroundExceptionDispatcher)
        {
            if (updateCommand == null)
            {
                return(null);
            }

            TimeSpan         initialDelay = FunctionOutputIntervals.InitialDelay;
            TimeSpan         refreshRate  = FunctionOutputIntervals.RefreshRate;
            ITaskSeriesTimer timer        = FixedDelayStrategy.CreateTimer(updateCommand, initialDelay, refreshRate, backgroundExceptionDispatcher);

            timer.Start();

            return(timer);
        }
        private static ITaskSeriesTimer StartParameterLogTimer(IRecurrentCommand updateCommand, IWebJobsExceptionHandler exceptionHandler)
        {
            if (updateCommand == null)
            {
                return(null);
            }

            TimeSpan         initialDelay = FunctionParameterLogIntervals.InitialDelay;
            TimeSpan         refreshRate  = FunctionParameterLogIntervals.RefreshRate;
            ITaskSeriesTimer timer        = FixedDelayStrategy.CreateTimer(updateCommand, initialDelay, refreshRate, exceptionHandler);

            timer.Start();

            return(timer);
        }
        private async Task ExecuteWithLoggingAsync(IFunctionInstance instance,
                                                   IReadOnlyDictionary <string, IValueProvider> parameters,
                                                   TraceWriter trace,
                                                   ILogger logger,
                                                   IFunctionOutputDefinition outputDefinition,
                                                   IDictionary <string, ParameterLog> parameterLogCollector,
                                                   TraceLevel functionTraceLevel,
                                                   CancellationTokenSource functionCancellationTokenSource)
        {
            IFunctionInvoker invoker = instance.Invoker;

            IReadOnlyDictionary <string, IWatcher> parameterWatchers = null;
            ITaskSeriesTimer updateParameterLogTimer = null;

            if (functionTraceLevel >= TraceLevel.Info)
            {
                parameterWatchers = CreateParameterWatchers(parameters);
                IRecurrentCommand updateParameterLogCommand = outputDefinition.CreateParameterLogUpdateCommand(parameterWatchers, trace, logger);
                updateParameterLogTimer = StartParameterLogTimer(updateParameterLogCommand, _exceptionHandler);
            }

            try
            {
                await ExecuteWithWatchersAsync(instance, parameters, trace, logger, functionCancellationTokenSource);

                if (updateParameterLogTimer != null)
                {
                    // Stop the watches after calling IValueBinder.SetValue (it may do things that should show up in
                    // the watches).
                    // Also, IValueBinder.SetValue could also take a long time (flushing large caches), and so it's
                    // useful to have watches still running.
                    await updateParameterLogTimer.StopAsync(functionCancellationTokenSource.Token);
                }
            }
            finally
            {
                if (updateParameterLogTimer != null)
                {
                    ((IDisposable)updateParameterLogTimer).Dispose();
                }

                if (parameterWatchers != null)
                {
                    ValueWatcher.AddLogs(parameterWatchers, parameterLogCollector);
                }
            }
        }
Esempio n. 31
0
        public async Task <IDelayedException> TryExecuteAsync(IFunctionInstance instance, CancellationToken cancellationToken)
        {
            IDelayedException result;

            using (ITaskSeriesTimer timer = CreateHeartbeatTimer(_exceptionHandler))
            {
                await _heartbeatCommand.TryExecuteAsync(cancellationToken);

                timer.Start();

                result = await _innerExecutor.TryExecuteAsync(instance, cancellationToken);

                await timer.StopAsync(cancellationToken);
            }

            return(result);
        }
Esempio n. 32
0
        public void StopAsync_IfAlreadyStopped_Throws()
        {
            // Arrange
            ITaskSeriesCommand command = CreateStubCommand(TimeSpan.Zero);

            using (ITaskSeriesTimer product = CreateProductUnderTest(command))
            {
                product.Start();
                product.StopAsync(CancellationToken.None).GetAwaiter().GetResult();

                CancellationToken cancellationToken = CancellationToken.None;

                // Act & Assert
                ExceptionAssert.ThrowsInvalidOperation(() => product.StopAsync(cancellationToken),
                                                       "The timer has already been stopped.");
            }
        }
Esempio n. 33
0
        public void Start_AfterExecute_WaitsForReturnedWait()
        {
            // Arrange
            bool     executedOnce    = false;
            bool     executedTwice   = false;
            TimeSpan initialInterval = TimeSpan.Zero;
            // Detect the difference between waiting and not waiting, but keep the test execution time fast.
            TimeSpan  subsequentInterval = TimeSpan.FromMilliseconds(5);
            Stopwatch stopwatch          = new Stopwatch();

            using (EventWaitHandle waitForSecondExecution = new ManualResetEvent(initialState: false))
            {
                ITaskSeriesCommand command = CreateCommand(() =>
                {
                    if (executedTwice)
                    {
                        return(new TaskSeriesCommandResult(wait: Task.Delay(TimeSpan.FromDays(1))));
                    }

                    if (!executedOnce)
                    {
                        stopwatch.Start();
                        executedOnce = true;
                        return(new TaskSeriesCommandResult(wait: Task.Delay(subsequentInterval)));
                    }
                    else
                    {
                        stopwatch.Stop();
                        executedTwice = true;
                        Assert.True(waitForSecondExecution.Set()); // Guard
                        return(new TaskSeriesCommandResult(wait: Task.Delay(initialInterval)));
                    }
                });

                using (ITaskSeriesTimer product = CreateProductUnderTest(command))
                {
                    // Act
                    product.Start();

                    // Assert
                    Assert.True(waitForSecondExecution.WaitOne(1000)); // Guard
                    AssertGreaterThan(subsequentInterval, stopwatch.Elapsed);
                }
            }
        }
        public SharedBlobListener(string hostId, BlobServiceClient blobServiceClient,
                                  IWebJobsExceptionHandler exceptionHandler, ILogger <BlobListener> logger)
        {
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            if (exceptionHandler == null)
            {
                throw new ArgumentNullException(nameof(exceptionHandler));
            }

            _strategy = CreateStrategy(hostId, blobServiceClient, exceptionHandler, logger);

            // Start the first iteration immediately.
            _timer = new TaskSeriesTimer(_strategy, exceptionHandler, initialWait: Task.Delay(0));
        }
 public TimerListener(ITaskSeriesTimer timer)
 {
     _timer = timer;
 }