/// <summary>
        /// Performs analysis of the document. Returns document global scope
        /// with declared variables and inner scopes. Does not analyze chain
        /// of dependencies, it is intended for the single file analysis.
        /// </summary>
        private void Analyze(IDependencyChainNode <PythonAnalyzerEntry> node, AsyncCountdownEvent ace, Stopwatch stopWatch)
        {
            try {
                var entry = node.Value;
                if (!CanUpdateAnalysis(entry, node, _walker.Version, out var module, out var ast, out var currentAnalysis))
                {
                    return;
                }
                var startTime = stopWatch.Elapsed;
                AnalyzeEntry(node, entry, module, ast, _walker.Version);

                LogCompleted(node, module, stopWatch, startTime);
            } catch (OperationCanceledException oce) {
                node.Value.TryCancel(oce, _walker.Version);
                LogCanceled(node.Value.Module);
            } catch (Exception exception) {
                node.Value.TrySetException(exception, _walker.Version);
                node.MarkWalked();
                LogException(node.Value.Module, exception);
            } finally {
                node.MoveNext();

                lock (_syncObj) {
                    if (!_isCanceled)
                    {
                        _progress.ReportRemaining(_walker.Remaining);
                    }
                    _runningTasks--;
                    ace?.Signal();
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Performs analysis of the document. Returns document global scope
        /// with declared variables and inner scopes. Does not analyze chain
        /// of dependencies, it is intended for the single file analysis.
        /// </summary>
        private void Analyze(IDependencyChainNode <PythonAnalyzerEntry> node, AsyncCountdownEvent ace, Stopwatch stopWatch)
        {
            try {
                var entry = node.Value;

                if (!entry.CanUpdateAnalysis(_walker.Version, out var module, out var ast, out var currentAnalysis))
                {
                    if (IsAnalyzedLibraryInLoop(node, currentAnalysis))
                    {
                        return;
                    }
                    else if (ast == default)
                    {
                        if (currentAnalysis == default)
                        {
                            // Entry doesn't have ast yet. There should be at least one more session.
                            Cancel();
                        }
                        else
                        {
                            Debug.Fail($"Library module {module.Name} of type {module.ModuleType} has been analyzed already!");
                        }
                    }

                    _log?.Log(TraceEventType.Verbose, $"Analysis of {module.Name}({module.ModuleType}) canceled.");
                    return;
                }

                var startTime = stopWatch.Elapsed;
                AnalyzeEntry(node, entry, module, ast, _walker.Version);

                LogCompleted(node, module, stopWatch, startTime);
            } catch (OperationCanceledException oce) {
                node.Value.TryCancel(oce, _walker.Version);
                LogCanceled(node.Value.Module);
            } catch (Exception exception) {
                node.Value.TrySetException(exception, _walker.Version);
                node.MarkWalked();
                LogException(node.Value.Module, exception);
            } finally {
                node.MoveNext();

                bool isCanceled;
                lock (_syncObj) {
                    isCanceled = _isCanceled;
                }

                if (!isCanceled)
                {
                    _progress.ReportRemaining(_walker.Remaining);
                }

                Interlocked.Decrement(ref _runningTasks);
                ace?.Signal();
            }
        }
 public void ItCompletesTheTaskWhenSignalIsCalledSampleTimes()
 {
     var asyncACE = new AsyncCountdownEvent(SampleTimes);
     var task = asyncACE.WaitAsync();
     for (int i = 0; i < SampleTimes; i++)
     {
         asyncACE.Signal();
     }
     task.Wait(TimeSpan.FromSeconds(1));
     Assert.IsTrue(task.IsCompleted);
 }
        private void Analyze(IDependencyChainNode node, AsyncCountdownEvent ace, Stopwatch stopWatch)
        {
            var loopAnalysis = false;

            try {
                switch (node)
                {
                case IDependencyChainSingleNode <PythonAnalyzerEntry> single:
                    try {
                        Analyze(single, stopWatch);
                    } catch (OperationCanceledException oce) {
                        single.Value.TryCancel(oce, _walker.Version);
                        LogCanceled(single.Value.Module);
                    } catch (Exception exception) {
                        single.Value.TrySetException(exception, _walker.Version);
                        node.MarkWalked();
                        LogException(single.Value, exception);
                    }

                    break;

                case IDependencyChainLoopNode <PythonAnalyzerEntry> loop:
                    try {
                        loopAnalysis = true;
                        AnalyzeLoop(loop, stopWatch);
                    } catch (OperationCanceledException) {
                        //loop.Value.TryCancel(oce, _walker.Version);
                        //LogCanceled(single.Value.Module);
                    } catch (Exception exception) {
                        //loop.Value.TrySetException(exception, _walker.Version);
                        node.MarkWalked();
                        LogException(loop, exception);
                    }

                    break;
                }
            } finally {
                node.MoveNext();

                bool isCanceled;
                lock (_syncObj) {
                    isCanceled = _isCanceled;
                }

                if (!isCanceled || loopAnalysis)
                {
                    _progress.ReportRemaining(_walker.Remaining);
                }

                Interlocked.Decrement(ref _runningTasks);
                ace?.Signal();
            }
        }
Esempio n. 5
0
        public async Task DataflowPipeBulkInsertBlockCoreAsync(AsyncCountdownEvent signals, int index, int orderCount)
        {
            #region Block Method
            (int blockCount, int minPerBlock, int maxPerBlock)blockBascInfo = BlockHelper.GetBasciBlockInfo(orderCount);
            int[] blockInfos = BlockHelper.GetBlockInfo(messageCount: orderCount, blockCount: blockBascInfo.blockCount, minPerBlock: blockBascInfo.minPerBlock, maxPerBlock: blockBascInfo.maxPerBlock);
            #endregion

            int boundedCapacity = blockInfos.Sum(b => b);
            Debug.Assert(orderCount == boundedCapacity);

            var logger = _loggerFactory.CreateLogger($"DataflowPipeBulkInserter-{index}");

            try
            {
                var contosoDataSourceFactory = this.ServiceProvider.GetRequiredService <IDataSourceFactory <IContosoDataSource> >();
                var orderDataSource          = contosoDataSourceFactory.Current.OrderDataSource;

                var      transportTimeWatcher = Stopwatch.StartNew();
                TimeSpan totalTransportTime   = TimeSpan.Zero;
                var      executionTimeWatcher = Stopwatch.StartNew();

                logger.LogInformation($"----begin dataflow pipe bulk insert {orderCount} orders,now:{DateTime.Now.TimeOfDay}----");

                int start = 0;
                for (int i = 0; i < blockInfos.Count(); i++)
                {
                    int insertOrderCount = blockInfos[i];
                    var orders           = OrderJsonProvider.CreateOrders(start, insertOrderCount);
                    start += insertOrderCount;

                    transportTimeWatcher.Restart();
                    var dbOrders = await orderDataSource.DataflowPipeBulkInsertOrdersAsync(orders);

                    totalTransportTime += transportTimeWatcher.Elapsed;
                    transportTimeWatcher.Reset();

                    //if (dbOrders?.Count() > 0)
                    //{
                    //    await ProcessDataflowPipeOrdersAsync(dbOrders);
                    //}
                }

                logger
                .LogInformation($"----dataflow pipe bulk insert {orderCount} orders,cost time:\"{executionTimeWatcher.Elapsed}\",transport time:{ totalTransportTime },count/time(sec):{Math.Ceiling(orderCount / totalTransportTime.TotalSeconds)},now:\"{DateTime.Now.TimeOfDay}\"----");

                signals?.Signal();
            }
            catch (Exception ex)
            {
                logger.LogError($"Error while dataflow pipe bulk insert orders of {nameof(DataflowPipeBulkInsertLoopCoreAsync)}: {ex.Message}");
            }
        }
        /// <summary>
        /// Performs analysis of the document. Returns document global scope
        /// with declared variables and inner scopes. Does not analyze chain
        /// of dependencies, it is intended for the single file analysis.
        /// </summary>
        private void Analyze(IDependencyChainNode <PythonAnalyzerEntry> node, AsyncCountdownEvent ace, Stopwatch stopWatch)
        {
            IPythonModule module;

            try {
                ace?.AddOne();
                var entry = node.Value;
                if (!entry.IsValidVersion(_walker.Version, out module, out var ast))
                {
                    if (ast == null)
                    {
                        // Entry doesn't have ast yet. There should be at least one more session.
                        Cancel();
                    }

                    _log?.Log(TraceEventType.Verbose, $"Analysis of {module.Name}({module.ModuleType}) canceled.");
                    node.Skip();
                    return;
                }
                var startTime = stopWatch.Elapsed;
                AnalyzeEntry(entry, module, ast, _walker.Version);
                node.Commit();

                _log?.Log(TraceEventType.Verbose, $"Analysis of {module.Name}({module.ModuleType}) completed in {(stopWatch.Elapsed - startTime).TotalMilliseconds} ms.");
            } catch (OperationCanceledException oce) {
                node.Value.TryCancel(oce, _walker.Version);
                node.Skip();
                module = node.Value.Module;
                _log?.Log(TraceEventType.Verbose, $"Analysis of {module.Name}({module.ModuleType}) canceled.");
            } catch (Exception exception) {
                module = node.Value.Module;
                node.Value.TrySetException(exception, _walker.Version);
                node.Commit();
                _log?.Log(TraceEventType.Verbose, $"Analysis of {module.Name}({module.ModuleType}) failed. Exception message: {exception.Message}.");
            } finally {
                bool isCanceled;
                lock (_syncObj) {
                    isCanceled = _isCanceled;
                }

                if (!isCanceled)
                {
                    _progress.ReportRemaining(_walker.Remaining);
                }

                Interlocked.Decrement(ref _runningTasks);
                ace?.Signal();
            }
        }
Esempio n. 7
0
        public async Task DataflowBulkInsertBlockRetryTasksCoreAsync(AsyncCountdownEvent signals, int index, int count, int orderCount)
        {
            var logger = _loggerFactory.CreateLogger($"DataflowBulkInserter-TaskCount:{index}");

            int totalOrderCount = count * orderCount;

            try
            {
                var dataflowBulkInserter = this.ServiceProvider.GetRequiredService<IDataflowBulkInserter<OrderDto, OrderDto>>();

                var contosoDataSourceFactory = this.ServiceProvider.GetRequiredService<IDataSourceFactory<IContosoDataSource>>();
                var orderDataSource = contosoDataSourceFactory.Current.OrderDataSource;

                // await Task.Delay(TimeSpan.FromMilliseconds(2000));

                var transportTimeWatcher = Stopwatch.StartNew();
                TimeSpan totalTransportTime = TimeSpan.Zero;
                var executionTimeWatcher = Stopwatch.StartNew();

               // logger.LogInformation($"----begin dataflow bulk insert { totalOrderCount} orders,now:{DateTime.Now.TimeOfDay}----");

                int start = 0;
                for (int i = 0; i < count; i++)
                {
                    var orders = OrderJsonProvider.CreateOrders(start, orderCount);
                    start += orderCount;

                    transportTimeWatcher.Restart();
                    var dbOrders = await orderDataSource.DataflowBulkInsertOrdersAsync(orders);
                    totalTransportTime += transportTimeWatcher.Elapsed;
                    transportTimeWatcher.Reset();

                    if (dbOrders?.Count() > 0)
                    {
                        await ProcessDataflowOrdersAsync(dbOrders);
                    }
                }

                //logger
                //  .LogInformation($"----dataflow bulk insert {totalOrderCount} orders,cost time:\"{executionTimeWatcher.Elapsed}\",transport time:{ totalTransportTime },count/time(sec):{Math.Ceiling(totalOrderCount / totalTransportTime.TotalSeconds)},now:\"{DateTime.Now.TimeOfDay}\"----");

                signals?.Signal();
            }
            catch (Exception ex)
            {
                logger.LogError($"Error while dataflow bulk insert orders of {nameof(DataflowBulkInsertBlockRetryTasksCoreAsync)}: {ex.Message}");
            }
        }
        /// <summary>
        /// Performs analysis of the document. Returns document global scope
        /// with declared variables and inner scopes. Does not analyze chain
        /// of dependencies, it is intended for the single file analysis.
        /// </summary>
        private void Analyze(IDependencyChainNode <PythonAnalyzerEntry> node, AsyncCountdownEvent ace, Stopwatch stopWatch)
        {
            try {
                ace?.AddOne();
                var entry = node.Value;

                if (!entry.IsValidVersion(_walker.Version, out var module, out var ast))
                {
                    if (ast == null)
                    {
                        // Entry doesn't have ast yet. There should be at least one more session.
                        Cancel();
                    }

                    _log?.Log(TraceEventType.Verbose, $"Analysis of {module.Name}({module.ModuleType}) canceled.");
                    node.Skip();
                    return;
                }

                var startTime = stopWatch.Elapsed;
                AnalyzeEntry(entry, module, _walker.Version, node.IsComplete);
                node.Commit();
                ActivityTracker.OnModuleAnalysisComplete(node.Value.Module.FilePath);

                LogCompleted(module, stopWatch, startTime);
            } catch (OperationCanceledException oce) {
                node.Value.TryCancel(oce, _walker.Version);
                node.Skip();
                LogCanceled(node.Value.Module);
            } catch (Exception exception) {
                node.Value.TrySetException(exception, _walker.Version);
                node.Commit();
                LogException(node.Value.Module, exception);
            } finally {
                bool isCanceled;
                lock (_syncObj) {
                    isCanceled = _isCanceled;
                }

                if (!isCanceled)
                {
                    _progress.ReportRemaining(_walker.Remaining);
                }

                Interlocked.Decrement(ref _runningTasks);
                ace?.Signal();
            }
        }
Esempio n. 9
0
        public async Task PipeBulkInsertLoopCoreAsync(AsyncCountdownEvent signals, int index, int count, int orderCount)
        {
            var logger = _loggerFactory.CreateLogger($"PipeBulkInserter-{index}");

            try
            {
                var contosoDataSourceFactory = this.ServiceProvider.GetRequiredService <IDataSourceFactory <IContosoDataSource> >();
                var orderDataSource          = contosoDataSourceFactory.Current.OrderDataSource;

                var      transportTimeWatcher = Stopwatch.StartNew();
                TimeSpan totalTransportTime   = TimeSpan.Zero;
                var      executionTimeWatcher = Stopwatch.StartNew();

                logger.LogInformation($"----begin pipe bulk insert {orderCount} orders,now:{DateTime.Now.TimeOfDay}----");

                int start = 0;
                for (int i = 0; i < count; i++)
                {
                    var orders = OrderJsonProvider.CreateOrders(start, orderCount);
                    start += orderCount;

                    transportTimeWatcher.Restart();
                    var dbOrders = await orderDataSource.PipeBulkInsertOrdersAsync(orders);

                    totalTransportTime += transportTimeWatcher.Elapsed;
                    transportTimeWatcher.Reset();

                    //if (dbOrders?.Count() > 0)
                    //{
                    //    await ProcessPipeOrdersAsync(dbOrders);
                    //}
                }

                logger
                .LogInformation($"----pipe bulk insert {orderCount} orders,cost time:\"{executionTimeWatcher.Elapsed}\",transport time:{ totalTransportTime },count/time(sec):{Math.Ceiling(orderCount / totalTransportTime.TotalSeconds)},now:\"{DateTime.Now.TimeOfDay}\"----");

                signals?.Signal();
            }
            catch (Exception ex)
            {
                logger.LogError($"Error while pipe bulk insert orders of {nameof(PipeBulkInsertLoopCoreAsync)}: {ex.Message}");
            }
        }
Esempio n. 10
0
        public void RegisterCallBackOnDataflowBulkInsert(IDataflowBulkInserter <OrderDto, OrderDto> sender, ILogger logger, AsyncCountdownEvent signals = null)
        {
            sender.OnInsertCallBack = async(context) =>
            {
                if (context.Exception != null)
                {
                    logger.LogError($"exception: {context.Exception} when send {context.MessageConunt} messages");
                }
                else if (context.ExecutionTime != TimeSpan.Zero)
                {
                    using (await _mutex.LockAsync())
                    {
                        _durationManage.MaxTime     = _durationManage.GetMaxTimeValue(_durationManage.MaxTime, context.ExecutionTime);
                        _durationManage.TotalTime  += context.ExecutionTime;
                        _durationManage.TotalCount += context.MessageConunt;
                    }

                    logger
                    .LogInformation($"TotalCount={ _durationManage.TotalCount},ExecutionTime={context.ExecutionTime},ThreadId={Thread.CurrentThread.ManagedThreadId},OrderCount=\"{context.MessageConunt}\"");
                }

                signals?.Signal();
            };
        }
        public void SignalThrowsOnError()
        {
            var evt = new AsyncCountdownEvent(0);

            Assert.Throws <InvalidOperationException>(() => evt.Signal());
        }
Esempio n. 12
0
        public async Task ProcessCrawlingQueueAsync(CrawlingQueue crawlingQueue)
        {
            _crawlingParameters.CancellationTokenSource.Token.Register(() =>
                                                                       crawlingQueue.QueueCancellationTokenSource.Cancel()
                                                                       );

            var tasksLock = new System.Threading.ReaderWriterLockSlim();
            var tasks     = new HashSet <Task>();

            var queueItemsProcessingSemaphore = new SemaphoreSlim(crawlingQueue.CrawlingConfiguration.MaxSimmultaneousQueueItemsProcessed / 2, crawlingQueue.CrawlingConfiguration.MaxSimmultaneousQueueItemsProcessed);

            while (await queueItemsProcessingSemaphore.WaitAsync(crawlingQueue.CrawlingConfiguration.MaxTimeToProcessOneQueueItem))
            {
                if (crawlingQueue.QueueCancellationTokenSource.IsCancellationRequested)
                {
                    await Task.WhenAll(tasks.ToArray());

                    // TODO: Move remaining items from local queue to the distributed queue
                    // TODO: Figure out how to filter out duplicates from the queue? Or should we?
                    //       We will probably have to resort to known urls-based duplicates check
                    //       Because otherwise we will drown in failing sql queries on multiplie machines

                    Trace.TraceWarning("ProcessCrawlingQueueAsync: Queue cancellation requested. Preventing dequeing of new elements. Processing will be shut down after currently executing items are complete.");
                    break;
                }

                var queueItem = await crawlingQueue.DequeueAsync();

                if (queueItem == null) // Both Local and Proxy queues are depleted
                {
                    // NOTE: If Queue is depleted, we must wait until all running tasks are executed, because they might add new items to queue
                    await Task.WhenAll(tasks.ToArray());

                    // wait for all queue proxies to complete fetching items
                    // TODO: consider locking (multithreading scenario)
                    var queueProxiesPending = crawlingQueue.QueueProxies.Where(queueProxy => queueProxy.IsPending()).ToArray();
                    if (queueProxiesPending.Length > 0)
                    {
                        continue;
                    }

                    if (crawlingQueue.LocalQueue.Count > 0)
                    {
                        continue;
                    }

                    break;
                }

                if (!await _crawlingEventInterceptorManager.OnAfterDequeueAsync(queueItem))
                {
                    // If interceptor returns false, means it's an instruction to ignore this item;
                    continue;
                }

                tasksLock.EnterWriteLock();

                queueItem.ChangeStatus(CrawlingQueueItem.CrawlingStatuses.Downloading);

                tasks.Add(System.Threading.Tasks.TaskExtensions.Unwrap(
                              CrawlAsync(queueItem.ResourceLink)
                              .ContinueWith(async task =>
                {
                    tasksLock.EnterWriteLock();
                    tasks.Remove(task);         // to avoid infinite bloating of the collection
                    tasksLock.ExitWriteLock();

                    try
                    {
                        queueItem.ChangeStatus(CrawlingQueueItem.CrawlingStatuses.Downloaded);

                        if (task.Status == TaskStatus.RanToCompletion)
                        {
                            var resourceContentUnits = task.Result;
                            var httpResultUnit       = resourceContentUnits.OfType <HttpResultUnit>().Single();

                            queueItem.ChangeStatus(CrawlingQueueItem.CrawlingStatuses.Processing);

                            var resourceContentUnitsProcessingCountdown = new AsyncCountdownEvent(resourceContentUnits.Count);

                            // Process resource content units extracted from Response
                            foreach (var resourceContentUnit in resourceContentUnits)
                            {
                                switch (resourceContentUnit)
                                {
                                case ExtractedLinksUnit extractedLinksUnit:
                                    if (extractedLinksUnit.ExtractedLinks.Count > 0)
                                    {
                                        var linksProcessingCountdown = new AsyncCountdownEvent(extractedLinksUnit.ExtractedLinks.Count);

                                        foreach (var extractedLink in extractedLinksUnit.ExtractedLinks)
                                        {
                                            var crawlingQueueItem = new CrawlingQueueItem(extractedLink);

                                            // Do not enqueue item if prevented by any interceptor
                                            if (!await _crawlingEventInterceptorManager.OnBeforeEnqueueAsync(crawlingQueueItem))
                                            {
                                                continue;
                                            }

                                            crawlingQueueItem.ProcessingCompleted += () =>
                                                                                     linksProcessingCountdown.AddCount(1)
                                            ;
                                            crawlingQueue.Enqueue(crawlingQueueItem);
                                        }

                                        // Wait while all links are processed before releasing the content units semaphore and set Status = Processed for parent
                                        linksProcessingCountdown.WaitAsync()
                                        .ContinueWith(linksProcessingTask =>
                                                      resourceContentUnitsProcessingCountdown.AddCount(1)
                                                      );
                                    }
                                    else
                                    {
                                        resourceContentUnitsProcessingCountdown.AddCount(1);
                                    }

                                    // Set Processed status when all extracted links are processed

                                    break;

                                case ExtractedDataUnit extractedDataUnit:
                                    if (!await _crawlingEventInterceptorManager.OnDataDocumentDownloadedAsync(
                                            queueItem.ResourceLink,             // May be a DocumentLink, or a FrameLink. Not quite intuitive and probably requires redesign.
                                            extractedDataUnit,
                                            httpResultUnit
                                            ))
                                    {
                                        // If any of interceptors failed to process the download result,
                                        // AND failed to store download result for later processing
                                        // we must re-enqueue the item, in order to ensure the results are not lost for good


                                        // We ignore the item and log the error. Chances are we couldn't process the item for a reason. And repeating would just make it stuck infinitely (re-downloading and re-processing)
                                        // (WAS) we must re-enqueue the item, in order to ensure the results are not lost for good

                                        //crawlingQueue.EnqueueAsync(queueItem);
                                    }
                                    resourceContentUnitsProcessingCountdown.Signal();
                                    break;

                                case DownloadedFilesUnit downloadedFileUnit:
                                    // If download file is a result of redirection,
                                    // we must either explicitly declare that we're expecting a file, or throw a processing exception

                                    var fileLink = queueItem.ResourceLink as FileLink;
                                    if (fileLink == null)
                                    {
                                        Trace.TraceError($"ProcessCrawlingQueueAsync: Downloaded file unit. Resource link is of type {queueItem.ResourceLink.GetType().Name}, expecting FileLink. Preventing processing.");
                                        break;
                                    }

                                    if (!await _crawlingEventInterceptorManager.OnFileDownloadedAsync(
                                            fileLink,
                                            downloadedFileUnit,
                                            httpResultUnit
                                            ))
                                    {
                                        // If any of interceptors failed to process the download result,
                                        // AND failed to store download result for later processing....

                                        // We ignore the item and log the error. Chances are we couldn't process the item for a reason. And repeating would just make it stuck infinitely (re-downloading and re-processing)
                                        // (WAS) we must re-enqueue the item, in order to ensure the results are not lost for good

                                        //crawlingQueue.EnqueueAsync(queueItem);
                                    }

                                    resourceContentUnitsProcessingCountdown.Signal();
                                    break;

                                case HttpResultUnit httpResultUnitStub:
                                    // TODO: Determine what we should do if HTTP download failed. Either re-enqueue or ignore, or alert/do something else
                                    switch (httpResultUnitStub.HttpStatus)
                                    {
                                    //case HttpStatusCode.InternalServerError: // it's likely to repeat within the same run
                                    case HttpStatusCode.GatewayTimeout:
                                    case HttpStatusCode.RequestTimeout:
                                        queueItem.ChangeStatus(CrawlingQueueItem.CrawlingStatuses.NotLinked);
                                        crawlingQueue.Enqueue(queueItem);                 // Trying to recrawl item if it failed for some intermitent reason
                                        break;

                                    default:
                                        // We need to invoke ProcessingCompleted only after Data and Links extracted are really processed.
                                        //queueItem.ChangeStatus(CrawlingQueueItem.CrawlingStatuses.ProcessingCompleted);
                                        break;
                                    }
                                    resourceContentUnitsProcessingCountdown.Signal();
                                    break;

                                default:
                                    throw new NotSupportedException();
                                }
                            }

                            // Do not actually wait for related resources processing completion.
                            // Those might be extracted links or files. No need to hold queue resources while linked units are downloaded
                            // Set Processed status after all content units were registered and interceptors triggered
                            await resourceContentUnitsProcessingCountdown.WaitAsync()
                            .ContinueWith(resourceContentUnitsProcessingTask =>
                                          queueItem.ChangeStatus(CrawlingQueueItem.CrawlingStatuses.Processed)
                                          );
                        }
                        else
                        {
                            Trace.TraceError("CrawlAsync: Failed for queue item {0} with exception [{1}]", queueItem.ResourceLink, task.Exception);
                        }
                    }
                    finally
                    {
                        queueItemsProcessingSemaphore.Release();
                    }
                })
                              )
                          );

                tasksLock.ExitWriteLock();
            }

            await Task.WhenAll(tasks.ToArray());
        }
        public async Task CanReindexVersionedIndexWithDeletedDocsAsync()
        {
            var version1Index = new VersionedEmployeeIndex(_configuration, 1);
            await version1Index.DeleteAsync();

            var version2Index = new VersionedEmployeeIndex(_configuration, 2);
            await version2Index.DeleteAsync();

            using (new DisposableAction(() => version1Index.DeleteAsync().GetAwaiter().GetResult())) {
                await version1Index.ConfigureAsync();

                Assert.True((await _client.Indices.ExistsAsync(version1Index.VersionedName)).Exists);

                IEmployeeRepository repository = new EmployeeRepository(_configuration);
                var employee = await repository.AddAsync(EmployeeGenerator.Default, o => o.ImmediateConsistency());

                Assert.NotNull(employee?.Id);

                using (new DisposableAction(() => version2Index.DeleteAsync().GetAwaiter().GetResult())) {
                    await version2Index.ConfigureAsync();

                    Assert.True((await _client.Indices.ExistsAsync(version2Index.VersionedName)).Exists);
                    Assert.Equal(1, await version2Index.GetCurrentVersionAsync());

                    // alias should still point to the old version until reindex
                    var aliasResponse = await _client.Indices.GetAliasAsync(version2Index.Name);

                    _logger.LogRequest(aliasResponse);
                    Assert.True(aliasResponse.IsValid);
                    Assert.Equal(1, aliasResponse.Indices.Count);
                    Assert.Equal(version1Index.VersionedName, aliasResponse.Indices.First().Key);

                    var countdown   = new AsyncCountdownEvent(1);
                    var reindexTask = version2Index.ReindexAsync(async(progress, message) => {
                        _logger.LogInformation($"Reindex Progress {progress}%: {message}");
                        if (progress == 91)
                        {
                            countdown.Signal();
                            await Task.Delay(1000);
                        }
                    });

                    // Wait until the first reindex pass is done.
                    await countdown.WaitAsync();

                    Assert.Equal(1, await version1Index.GetCurrentVersionAsync());
                    await repository.RemoveAllAsync(o => o.ImmediateConsistency());

                    // Resume after everythings been indexed.
                    await reindexTask;
                    aliasResponse = await _client.Indices.GetAliasAsync(version2Index.Name);

                    _logger.LogRequest(aliasResponse);
                    Assert.True(aliasResponse.IsValid, aliasResponse.GetErrorMessage());
                    Assert.Equal(1, aliasResponse.Indices.Count);
                    Assert.Equal(version2Index.VersionedName, aliasResponse.Indices.First().Key);

                    Assert.Equal(2, await version1Index.GetCurrentVersionAsync());
                    Assert.Equal(2, await version2Index.GetCurrentVersionAsync());

                    var countResponse = await _client.CountAsync <Employee>(d => d.Index(version1Index.VersionedName));

                    _logger.LogRequest(countResponse);
                    Assert.True(countResponse.ApiCall.HttpStatusCode == 404, countResponse.GetErrorMessage());
                    Assert.Equal(0, countResponse.Count);

                    countResponse = await _client.CountAsync <Employee>(d => d.Index(version2Index.VersionedName));

                    _logger.LogRequest(countResponse);
                    Assert.True(countResponse.IsValid, countResponse.GetErrorMessage());
                    Assert.Equal(1, countResponse.Count);

                    Assert.Equal(employee, await repository.GetByIdAsync(employee.Id));
                    Assert.False((await _client.Indices.ExistsAsync(version1Index.VersionedName)).Exists);
                }
            }
        }
        public async Task CanIncrementUsageAsync()
        {
            var cache = IoC.GetInstance <ICacheClient>() as InMemoryCacheClient;

            Assert.NotNull(cache);
            await cache.RemoveAllAsync();

            var countdown        = new AsyncCountdownEvent(2);
            var messagePublisher = IoC.GetInstance <IMessagePublisher>() as InMemoryMessageBus;

            Assert.NotNull(messagePublisher);
            messagePublisher.Subscribe <PlanOverage>(po => {
                _logger.Info($"Plan Overage for {po.OrganizationId} (Hourly: {po.IsHourly})");
                countdown.Signal();
            });

            var o = await _repository.AddAsync(new Organization { Name = "Test", MaxEventsPerMonth = 750, PlanId = BillingManager.FreePlan.Id });

            await _client.RefreshAsync();

            Assert.InRange(o.GetHourlyEventLimit(), 1, 750);

            int totalToIncrement = o.GetHourlyEventLimit() - 1;

            Assert.False(await _repository.IncrementUsageAsync(o.Id, false, totalToIncrement));
            await _client.RefreshAsync();

            o = await _repository.GetByIdAsync(o.Id);

            await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

            Assert.Equal(2, countdown.CurrentCount);
            Assert.Equal(totalToIncrement, await cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id), 0));
            Assert.Equal(totalToIncrement, await cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id), 0));
            Assert.Equal(0, await cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(0, await cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id), 0));

            Assert.True(await _repository.IncrementUsageAsync(o.Id, false, 2));
            await _client.RefreshAsync();

            o = await _repository.GetByIdAsync(o.Id);

            await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

            Assert.Equal(1, countdown.CurrentCount);
            Assert.Equal(totalToIncrement + 2, await cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id), 0));
            Assert.Equal(totalToIncrement + 2, await cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id), 0));
            Assert.Equal(1, await cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(1, await cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id), 0));

            o = await _repository.AddAsync(new Organization { Name = "Test", MaxEventsPerMonth = 750, PlanId = BillingManager.FreePlan.Id });

            await _client.RefreshAsync();

            totalToIncrement = o.GetHourlyEventLimit() + 20;
            Assert.True(await _repository.IncrementUsageAsync(o.Id, false, totalToIncrement));

            await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

            Assert.Equal(0, countdown.CurrentCount);
            Assert.Equal(totalToIncrement, await cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id), 0));
            Assert.Equal(totalToIncrement, await cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id), 0));
            Assert.Equal(20, await cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(20, await cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id), 0));
        }
        public async Task Any_given_lease_is_never_handed_out_to_more_than_one_handler_at_a_time()
        {
            var random = new Random();
            var currentlyGranted = new HashSet<string>();
            var everGranted = new HashSet<string>();
            var leasedConcurrently = "";
            var distributor = CreateDistributor(waitInterval: TimeSpan.FromSeconds(5)).Trace();
            var countDown = new AsyncCountdownEvent(10);

            distributor.OnReceive(async lease =>
            {
                lock (currentlyGranted)
                {
                    if (currentlyGranted.Contains(lease.LeasableResource.Name))
                    {
                        leasedConcurrently = lease.LeasableResource.Name;
                    }

                    currentlyGranted.Add(lease.LeasableResource.Name);
                    everGranted.Add(lease.LeasableResource.Name);
                }

                await Task.Delay((int) (1000*random.NextDouble()));

                lock (currentlyGranted)
                {
                    currentlyGranted.Remove(lease.LeasableResource.Name);
                }

                countDown.Signal();
            });

            Enumerable.Range(1, 10).ToList().ForEach(_ => { distributor.Distribute(1); });
            await countDown.WaitAsync().Timeout();

            leasedConcurrently.Should().BeEmpty();
            everGranted.Count.Should().Be(10);
        }
 /// <summary>
 /// Registers a task with the ASP.NET runtime.
 /// </summary>
 /// <param name="task">The task to register.</param>
 private void Register(Task task)
 {
     count.AddCount();
     task.ContinueWith(_ => count.Signal(), TaskContinuationOptions.ExecuteSynchronously);
 }
Esempio n. 17
0
        protected async Task CanHaveMultipleQueueInstancesWithLockingImplAsync(CacheLockProvider distributedLock)
        {
            var queue = GetQueue(retries: 0, retryDelay: TimeSpan.Zero);

            if (queue == null)
            {
                return;
            }

            try {
                await queue.DeleteQueueAsync();
                await AssertEmptyQueueAsync(queue);

                const int workItemCount = 16;
                const int workerCount   = 4;
                var       countdown     = new AsyncCountdownEvent(workItemCount);
                var       info          = new WorkInfo();
                var       workers       = new List <IQueue <SimpleWorkItem> > {
                    queue
                };

                try {
                    for (int i = 0; i < workerCount; i++)
                    {
                        var q             = GetQueue(retries: 0, retryDelay: TimeSpan.Zero);
                        int instanceCount = i;
                        await q.StartWorkingAsync(async w => {
                            _logger.Info("[{0}] Acquiring distributed lock in work item: {1}", instanceCount, w.Id);
                            var l = await distributedLock.AcquireAsync("test");
                            Assert.NotNull(l);
                            _logger.Info("[{0}] Acquired distributed lock: {1}", instanceCount, w.Id);
                            SystemClock.Sleep(TimeSpan.FromMilliseconds(50));
                            await l.ReleaseAsync();
                            _logger.Info("[{0}] Released distributed lock: {1}", instanceCount, w.Id);

                            await w.CompleteAsync();
                            info.IncrementCompletedCount();
                            countdown.Signal();
                            _logger.Info("[{0}] Signaled countdown: {1}", instanceCount, w.Id);
                        });

                        workers.Add(q);
                    }

                    await Run.InParallelAsync(workItemCount, async i => {
                        string id = await queue.EnqueueAsync(new SimpleWorkItem {
                            Data = "Hello",
                            Id   = i
                        });
                        _logger.Trace("Enqueued Index: {0} Id: {1}", i, id);
                    });

                    await countdown.WaitAsync(TimeSpan.FromSeconds(5).ToCancellationToken());

                    await SystemClock.SleepAsync(50);

                    _logger.Trace("Completed: {0} Abandoned: {1} Error: {2}", info.CompletedCount, info.AbandonCount, info.ErrorCount);

                    _logger.Info("Work Info Stats: Completed: {completed} Abandoned: {abandoned} Error: {errors}", info.CompletedCount, info.AbandonCount, info.ErrorCount);
                    Assert.Equal(workItemCount, info.CompletedCount + info.AbandonCount + info.ErrorCount);

                    // In memory queue doesn't share state.
                    if (queue.GetType() == typeof(InMemoryQueue <SimpleWorkItem>))
                    {
                        var stats = await queue.GetQueueStatsAsync();

                        Assert.Equal(info.CompletedCount, stats.Completed);
                    }
                    else
                    {
                        var workerStats = new List <QueueStats>();
                        for (int i = 0; i < workers.Count; i++)
                        {
                            var stats = await workers[i].GetQueueStatsAsync();
                            _logger.Info("Worker#{i} Working: {working} Completed: {completed} Abandoned: {abandoned} Error: {errors} Deadletter: {deadletter}", i, stats.Working, stats.Completed, stats.Abandoned, stats.Errors, stats.Deadletter);
                            workerStats.Add(stats);
                        }

                        Assert.Equal(info.CompletedCount, workerStats.Sum(s => s.Completed));
                    }
                } finally {
                    foreach (var q in workers)
                    {
                        await CleanupQueueAsync(q);
                    }
                }
            } finally {
                await CleanupQueueAsync(queue);
            }
        }
        public async Task WatchAllEvents()
        {
            AsyncCountdownEvent   eventsReceived = new AsyncCountdownEvent(4 /* first line of response is eaten by WatcherDelegatingHandler */);
            AsyncManualResetEvent serverShutdown = new AsyncManualResetEvent();
            var waitForClosed = new AsyncManualResetEvent(false);

            using (var server = new MockKubeApiServer(testOutput, async httpContext =>
            {
                await WriteStreamLine(httpContext, MockAddedEventStreamLine);
                await WriteStreamLine(httpContext, MockDeletedStreamLine);
                await WriteStreamLine(httpContext, MockModifiedStreamLine);
                await WriteStreamLine(httpContext, MockErrorStreamLine);

                // make server alive, cannot set to int.max as of it would block response
                await serverShutdown.WaitAsync();
                return(false);
            }))
            {
                var client = new Kubernetes(new KubernetesClientConfiguration
                {
                    Host = server.Uri.ToString()
                });

                var listTask = await client.ListNamespacedPodWithHttpMessagesAsync("default", watch : true);

                var events = new HashSet <WatchEventType>();
                var errors = 0;

                var watcher = listTask.Watch <V1Pod, V1PodList>(
                    (type, item) =>
                {
                    testOutput.WriteLine($"Watcher received '{type}' event.");

                    events.Add(type);
                    eventsReceived.Signal();
                },
                    error =>
                {
                    testOutput.WriteLine($"Watcher received '{error.GetType().FullName}' error.");

                    errors += 1;
                    eventsReceived.Signal();
                },
                    onClosed: waitForClosed.Set
                    );

                // wait server yields all events
                await Task.WhenAny(eventsReceived.WaitAsync(), Task.Delay(TestTimeout));

                Assert.True(
                    eventsReceived.CurrentCount == 0,
                    "Timed out waiting for all events / errors to be received."
                    );

                Assert.Contains(WatchEventType.Added, events);
                Assert.Contains(WatchEventType.Deleted, events);
                Assert.Contains(WatchEventType.Modified, events);
                Assert.Contains(WatchEventType.Error, events);

                Assert.Equal(0, errors);

                Assert.True(watcher.Watching);

                serverShutdown.Set();

                await Task.WhenAny(waitForClosed.WaitAsync(), Task.Delay(TestTimeout));

                Assert.True(waitForClosed.IsSet);
                Assert.False(watcher.Watching);
            }
        }
Esempio n. 19
0
        public async Task <List <Task> > RunAsync(int numPushers, int numPullers, int numMessagesPerPusher, AsyncCountdownEvent counter, CancellationToken token)
        {
            var       inUrl      = UrlIpc();
            var       outUrl     = UrlIpc();
            const int numBrokers = 1;

            var brokersReady = new AsyncBarrier(numBrokers + 1);
            var clientsReady = new AsyncBarrier(numPushers + numPullers + numBrokers);

            var numForwarded = 0;
            var tasks        = new List <Task>();

            for (var i = 0; i < numBrokers; ++i)
            {
                var task = Task.Run(async() =>
                {
                    var pullSocket = implementation.CreateInSocket(inUrl);
                    var pushSocket = implementation.CreateOutSocket(outUrl);
                    await brokersReady.SignalAndWait(); // Broker is ready
                    await clientsReady.SignalAndWait(); // Wait for clients
                    while (!token.IsCancellationRequested)
                    {
                        var msg = await pullSocket.Receive(token);
                        await pushSocket.Send(msg.Unwrap());
                        ++numForwarded;
                    }
                });
                tasks.Add(task);
            }

            await brokersReady.SignalAndWait();

            for (var i = 0; i < numPushers; ++i)
            {
                var task = Task.Run(async() =>
                {
                    using (var socket = implementation.Factory.PusherOpen().ThenDial(inUrl).Unwrap())
                        using (var ctx = socket.CreateAsyncContext(implementation.Factory).Unwrap())
                        {
                            await clientsReady.SignalAndWait(); // This client ready, wait for rest
                            // Give all receivers a chance to actually start receiving
                            await WaitShort();
                            for (var m = 0; m < numMessagesPerPusher; ++m)
                            {
                                await ctx.Send(implementation.CreateMessage());
                                await WaitShort();
                            }
                        }
                });
                tasks.Add(task);
            }

            for (var i = 0; i < numPullers; ++i)
            {
                var task = Task.Run(async() =>
                {
                    var pullSocket = implementation.CreateClient(outUrl);
                    await clientsReady.SignalAndWait(); // This client ready, wait for rest
                    while (!token.IsCancellationRequested)
                    {
                        var _ = await pullSocket.Receive(token);
                        counter.Signal();
                    }
                });
                tasks.Add(task);
            }

            return(tasks);
        }
Esempio n. 20
0
        async Task DoContexts(string url)
        {
            const int NumSurveyors        = 1;
            const int NumResponders       = 3;
            var       readyToDial         = new AsyncBarrier(NumSurveyors + NumResponders);
            var       readyToSend         = new AsyncBarrier(NumSurveyors + NumResponders);
            var       numSurveyorReceive  = new AsyncCountdownEvent(NumSurveyors);
            var       numResponderReceive = new AsyncCountdownEvent(NumSurveyors);

            using (var surveySocket = Factory.SurveyorCreate(url, true).Unwrap())
                using (var respondSocket = Factory.RespondentCreate(url, false).Unwrap())
                {
                    var cts   = new CancellationTokenSource();
                    var tasks = new List <Task>();
                    for (var i = 0; i < NumSurveyors; ++i)
                    {
                        var task = Task.Run(async() =>
                        {
                            using (var ctx = surveySocket.CreateAsyncContext(Factory).Unwrap())
                            {
                                (ctx as ICtx).Ctx.SetOpt(Native.Defines.NNG_OPT_SURVEYOR_SURVEYTIME, new nng_duration {
                                    TimeMs = DefaultTimeoutMs
                                });

                                await readyToDial.SignalAndWait();
                                await readyToSend.SignalAndWait();

                                // Send survey and receive responses
                                var survey = Factory.CreateMessage();
                                //Assert.Equal(0, survey.Header.Append((uint)(0x8000000 | i))); // Protocol header contains "survey ID"
                                await ctx.Send(survey);
                                while (!cts.IsCancellationRequested)
                                {
                                    try
                                    {
                                        var response = await ctx.Receive(cts.Token);
                                        if (numSurveyorReceive.Signal() == 0)
                                        {
                                            break;
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        Console.Error.WriteLine(ex.ToString());
                                        throw ex;
                                    }
                                }
                            }
                        });
                        tasks.Add(task);
                    }

                    for (var i = 0; i < NumResponders; ++i)
                    {
                        var task = Task.Run(async() =>
                        {
                            await readyToDial.SignalAndWait();
                            using (var ctx = respondSocket.CreateAsyncContext(Factory).Unwrap())
                            {
                                await readyToSend.SignalAndWait();
                                try
                                {
                                    // Receive survey and send response
                                    var survey = await ctx.Receive(cts.Token);
                                    (await ctx.Send(survey.Unwrap())).Unwrap();
                                    numResponderReceive.Signal();
                                }
                                catch (Exception ex)
                                {
                                    Console.WriteLine(ex.ToString());
                                    throw ex;
                                }
                            }
                        });
                        tasks.Add(task);
                    }

                    await Util.CancelAfterAssertwait(tasks, cts);

                    Assert.Equal(0, numSurveyorReceive.Count);
                    Assert.Equal(0, numResponderReceive.Count);
                }
        }
Esempio n. 21
0
        async Task DoContexts(string url)
        {
            const int NumSurveyors        = 1;
            const int NumResponders       = 2;
            var       readyToDial         = new AsyncBarrier(NumSurveyors + NumResponders);
            var       readyToSend         = new AsyncBarrier(NumSurveyors + NumResponders);
            var       ready               = readyToSend.WaitAsync();
            var       numSurveyorReceive  = new AsyncCountdownEvent(NumSurveyors);
            var       numResponderReceive = new AsyncCountdownEvent(NumSurveyors);

            using (var surveySocket = Factory.SurveyorOpen().ThenListen(url).Unwrap())
                using (var respondSocket = Factory.RespondentOpen().ThenDial(url).Unwrap())
                {
                    var duration = new nng_duration {
                        TimeMs = DefaultTimeoutMs
                    };
                    // Send() is not cancelable so need it to timeout
                    surveySocket.SetOpt(nng.Native.Defines.NNG_OPT_SENDTIMEO, new nng_duration {
                        TimeMs = 50
                    });
                    surveySocket.SetOpt(nng.Native.Defines.NNG_OPT_RECVTIMEO, nng_duration.Infinite);
                    surveySocket.SetOpt(Native.Defines.NNG_OPT_SURVEYOR_SURVEYTIME, nng_duration.Infinite);
                    respondSocket.SetOpt(nng.Native.Defines.NNG_OPT_SENDTIMEO, new nng_duration {
                        TimeMs = 50
                    });

                    var cts   = new CancellationTokenSource();
                    var tasks = new List <Task>();
                    for (var i = 0; i < NumSurveyors; ++i)
                    {
                        var id   = i;
                        var task = Task.Run(async() =>
                        {
                            using (var ctx = surveySocket.CreateAsyncContext(Factory).Unwrap())
                            {
                                ctx.Ctx.SetOpt(Native.Defines.NNG_OPT_RECVTIMEO, nng_duration.Infinite);
                                ctx.Ctx.SetOpt(Native.Defines.NNG_OPT_SURVEYOR_SURVEYTIME, nng_duration.Infinite);

                                await readyToDial.SignalAndWait();
                                await readyToSend.SignalAndWait();

                                // Send survey and receive responses
                                var survey = Factory.CreateMessage();
                                var val    = (uint)rng.Next();
                                survey.Append(val);
                                //Assert.Equal(0, survey.Header.Append((uint)(0x8000000 | i))); // Protocol header contains "survey ID"
                                (await ctx.Send(survey)).Unwrap();
                                while (!cts.IsCancellationRequested)
                                {
                                    try
                                    {
                                        var response = (await ctx.Receive(cts.Token)).Unwrap();
                                        response.Trim(out uint respVal);
                                        Assert.Equal(val, respVal);
                                        if (numSurveyorReceive.Signal() == 0)
                                        {
                                            break;
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        Console.Error.WriteLine(ex.ToString());
                                        throw ex;
                                    }
                                }
                            }
                        });
                        tasks.Add(task);
                    }

                    for (var i = 0; i < NumResponders; ++i)
                    {
                        var id   = i;
                        var task = Task.Run(async() =>
                        {
                            await readyToDial.SignalAndWait();
                            using (var ctx = respondSocket.CreateAsyncContext(Factory).Unwrap())
                            {
                                // Receive survey and send response
                                try
                                {
                                    // Receive is async, give it a chance to start before signaling we are ready.
                                    // This to avoid race where surveyor sends before it actually starts receiving
                                    var recvFuture = ctx.Receive(cts.Token);
                                    await WaitShort();
                                    await readyToSend.SignalAndWait();
                                    var survey = (await recvFuture).Unwrap();
                                    await Task.Delay(10); // Make sure surveyor has a chance to start receiving
                                    (await ctx.Send(survey)).Unwrap();
                                    numResponderReceive.Signal();
                                    await numSurveyorReceive.WaitAsync();
                                    cts.Cancel(); // Cancel any responders still receiving
                                }
                                catch (Exception ex)
                                {
                                    Console.WriteLine(ex.ToString());
                                    throw ex;
                                }
                            }
                        });
                        tasks.Add(task);
                    }
                    await Task.WhenAny(ready, Task.WhenAll(tasks));

                    await Util.CancelAfterAssertwait(tasks, cts);

                    Assert.Equal(0, numSurveyorReceive.Count);
                    Assert.Equal(0, numResponderReceive.Count);
                }
        }
Esempio n. 22
0
 public Task Invoke(IncomingContext context, Func <Task> next)
 {
     countdown.Signal();
     return(next());
 }
Esempio n. 23
0
    public async Task CanIncrementSuspendedOrganizationUsageAsync()
    {
        var messageBus = GetService <IMessageBus>();

        var countdown = new AsyncCountdownEvent(2);
        await messageBus.SubscribeAsync <PlanOverage>(po => {
            _logger.LogInformation("Plan Overage for {organization} (Hourly: {IsHourly})", po.OrganizationId, po.IsHourly);
            countdown.Signal();
        });

        var organization = await _organizationRepository.AddAsync(new Organization { Name = "Test", MaxEventsPerMonth = 750, PlanId = _plans.SmallPlan.Id }, o => o.ImmediateConsistency());

        var project = await _projectRepository.AddAsync(new Project { Name = "Test", OrganizationId = organization.Id, NextSummaryEndOfDayTicks = SystemClock.UtcNow.Ticks }, o => o.ImmediateConsistency());

        Assert.False(await _usageService.IncrementUsageAsync(organization, project, 5));

        await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

        Assert.Equal(2, countdown.CurrentCount);

        var organizationUsage = await _usageService.GetUsageAsync(organization);

        var projectUsage = await _usageService.GetUsageAsync(organization, project);

        Assert.Equal(5, organizationUsage.HourlyTotal);
        Assert.Equal(5, projectUsage.HourlyTotal);
        Assert.Equal(5, organizationUsage.MonthlyTotal);
        Assert.Equal(5, projectUsage.MonthlyTotal);
        Assert.Equal(0, organizationUsage.HourlyBlocked);
        Assert.Equal(0, projectUsage.HourlyBlocked);
        Assert.Equal(0, organizationUsage.MonthlyBlocked);
        Assert.Equal(0, projectUsage.MonthlyBlocked);

        organization.IsSuspended       = true;
        organization.SuspendedByUserId = TestConstants.UserId;
        organization.SuspensionDate    = SystemClock.UtcNow;
        organization.SuspensionCode    = SuspensionCode.Billing;
        organization = await _organizationRepository.SaveAsync(organization, o => o.ImmediateConsistency());

        Assert.True(await _usageService.IncrementUsageAsync(organization, project, 4995));

        await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

        Assert.Equal(1, countdown.CurrentCount);

        organizationUsage = await _usageService.GetUsageAsync(organization);

        projectUsage = await _usageService.GetUsageAsync(organization, project);

        Assert.Equal(5000, organizationUsage.HourlyTotal);
        Assert.Equal(5000, projectUsage.HourlyTotal);
        Assert.Equal(5000, organizationUsage.MonthlyTotal);
        Assert.Equal(5000, projectUsage.MonthlyTotal);
        Assert.Equal(4995, organizationUsage.HourlyBlocked);
        Assert.Equal(4995, projectUsage.HourlyBlocked);
        Assert.Equal(4995, organizationUsage.MonthlyBlocked);
        Assert.Equal(4995, projectUsage.MonthlyBlocked);

        organization.RemoveSuspension();
        organization = await _organizationRepository.SaveAsync(organization, o => o.ImmediateConsistency());

        Assert.False(await _usageService.IncrementUsageAsync(organization, project, 1));
        await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

        Assert.Equal(1, countdown.CurrentCount);

        organizationUsage = await _usageService.GetUsageAsync(organization);

        projectUsage = await _usageService.GetUsageAsync(organization, project);

        Assert.Equal(5001, organizationUsage.HourlyTotal);
        Assert.Equal(5001, projectUsage.HourlyTotal);
        Assert.Equal(5001, organizationUsage.MonthlyTotal);
        Assert.Equal(5001, projectUsage.MonthlyTotal);
        Assert.Equal(4995, organizationUsage.HourlyBlocked);
        Assert.Equal(4995, projectUsage.HourlyBlocked);
        Assert.Equal(4995, organizationUsage.MonthlyBlocked);
        Assert.Equal(4995, projectUsage.MonthlyBlocked);
    }
Esempio n. 24
0
        public async Task CanReindexVersionedIndexWithUpdatedDocsAsync()
        {
            var version1Index = new VersionedEmployeeIndex(_configuration, 1);
            await version1Index.DeleteAsync();

            var version2Index = new VersionedEmployeeIndex(_configuration, 2);
            await version2Index.DeleteAsync();

            using (new DisposableAction(() => version1Index.DeleteAsync().GetAwaiter().GetResult())) {
                await version1Index.ConfigureAsync();

                Assert.True(_client.IndexExists(version1Index.VersionedName).Exists);

                var repository = new EmployeeRepository(version1Index.Employee);
                var employee   = await repository.AddAsync(EmployeeGenerator.Default, o => o.ImmediateConsistency());

                Assert.NotNull(employee?.Id);

                using (new DisposableAction(() => version2Index.DeleteAsync().GetAwaiter().GetResult())) {
                    await version2Index.ConfigureAsync();

                    Assert.True(_client.IndexExists(version2Index.VersionedName).Exists);
                    Assert.Equal(1, await version2Index.GetCurrentVersionAsync());

                    // alias should still point to the old version until reindex
                    var aliasResponse = await _client.GetAliasAsync(descriptor => descriptor.Name(version2Index.Name));

                    Assert.True(aliasResponse.IsValid);
                    Assert.Equal(1, aliasResponse.Indices.Count);
                    Assert.Equal(version1Index.VersionedName, aliasResponse.Indices.First().Key);

                    var countdown   = new AsyncCountdownEvent(1);
                    var reindexTask = version2Index.ReindexAsync((progress, message) => {
                        _logger.LogInformation($"Reindex Progress {progress}%: {message}");
                        if (progress == 91)
                        {
                            countdown.Signal();
                            SystemClock.Sleep(1000);
                        }

                        return(Task.CompletedTask);
                    });

                    // Wait until the first reindex pass is done.
                    await countdown.WaitAsync();

                    Assert.Equal(1, await version1Index.GetCurrentVersionAsync());
                    await repository.AddAsync(EmployeeGenerator.Generate(createdUtc: SystemClock.UtcNow));

                    employee.Name = "Updated";
                    await repository.SaveAsync(employee);

                    // Resume after everythings been indexed.
                    await reindexTask;
                    aliasResponse = await _client.GetAliasAsync(descriptor => descriptor.Name(version2Index.Name));

                    Assert.True(aliasResponse.IsValid);
                    Assert.Equal(1, aliasResponse.Indices.Count);
                    Assert.Equal(version2Index.VersionedName, aliasResponse.Indices.First().Key);

                    Assert.Equal(2, await version1Index.GetCurrentVersionAsync());
                    Assert.Equal(2, await version2Index.GetCurrentVersionAsync());

                    await _client.RefreshAsync(Indices.All);

                    var countResponse = await _client.CountAsync <Employee>(d => d.Index(version2Index.VersionedName));

                    _logger.LogTrace(countResponse.GetRequest());
                    Assert.True(countResponse.IsValid);
                    Assert.Equal(2, countResponse.Count);

                    var result = await repository.GetByIdAsync(employee.Id);

                    Assert.Equal(ToJson(employee), ToJson(result));
                    Assert.False((await _client.IndexExistsAsync(version1Index.VersionedName)).Exists);
                }
            }
        }
Esempio n. 25
0
    public async Task CanIncrementUsageAsync()
    {
        var messageBus = GetService <IMessageBus>();

        var countdown = new AsyncCountdownEvent(2);
        await messageBus.SubscribeAsync <PlanOverage>(po => {
            _logger.LogInformation("Plan Overage for {organization} (Hourly: {IsHourly})", po.OrganizationId, po.IsHourly);
            countdown.Signal();
        });

        var organization = await _organizationRepository.AddAsync(new Organization { Name = "Test", MaxEventsPerMonth = 750, PlanId = _plans.SmallPlan.Id }, o => o.ImmediateConsistency());

        var project = await _projectRepository.AddAsync(new Project { Name = "Test", OrganizationId = organization.Id, NextSummaryEndOfDayTicks = SystemClock.UtcNow.Ticks }, o => o.ImmediateConsistency());

        Assert.InRange(organization.GetHourlyEventLimit(_plans), 1, 750);

        int totalToIncrement = organization.GetHourlyEventLimit(_plans) - 1;

        Assert.False(await _usageService.IncrementUsageAsync(organization, project, totalToIncrement));
        organization = await _organizationRepository.GetByIdAsync(organization.Id);

        await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

        Assert.Equal(2, countdown.CurrentCount);
        var organizationUsage = await _usageService.GetUsageAsync(organization);

        var projectUsage = await _usageService.GetUsageAsync(organization, project);

        Assert.Equal(totalToIncrement, organizationUsage.HourlyTotal);
        Assert.Equal(totalToIncrement, projectUsage.HourlyTotal);
        Assert.Equal(totalToIncrement, organizationUsage.MonthlyTotal);
        Assert.Equal(totalToIncrement, projectUsage.MonthlyTotal);
        Assert.Equal(0, organizationUsage.HourlyBlocked);
        Assert.Equal(0, projectUsage.HourlyBlocked);
        Assert.Equal(0, organizationUsage.MonthlyBlocked);
        Assert.Equal(0, projectUsage.MonthlyBlocked);

        Assert.True(await _usageService.IncrementUsageAsync(organization, project, 2));
        await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

        Assert.Equal(1, countdown.CurrentCount);

        organizationUsage = await _usageService.GetUsageAsync(organization);

        projectUsage = await _usageService.GetUsageAsync(organization, project);

        Assert.Equal(totalToIncrement + 2, organizationUsage.HourlyTotal);
        Assert.Equal(totalToIncrement + 2, projectUsage.HourlyTotal);
        Assert.Equal(totalToIncrement + 2, organizationUsage.MonthlyTotal);
        Assert.Equal(totalToIncrement + 2, projectUsage.MonthlyTotal);
        Assert.Equal(1, organizationUsage.HourlyBlocked);
        Assert.Equal(1, projectUsage.HourlyBlocked);
        Assert.Equal(1, organizationUsage.MonthlyBlocked);
        Assert.Equal(1, projectUsage.MonthlyBlocked);

        organization = await _organizationRepository.AddAsync(new Organization { Name = "Test", MaxEventsPerMonth = 750, PlanId = _plans.SmallPlan.Id }, o => o.ImmediateConsistency());

        project = await _projectRepository.AddAsync(new Project { Name = "Test", OrganizationId = organization.Id, NextSummaryEndOfDayTicks = SystemClock.UtcNow.Ticks }, o => o.ImmediateConsistency());

        await _cache.RemoveAllAsync();

        totalToIncrement = organization.GetHourlyEventLimit(_plans) + 20;
        Assert.True(await _usageService.IncrementUsageAsync(organization, project, totalToIncrement));

        await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

        Assert.Equal(0, countdown.CurrentCount);

        organizationUsage = await _usageService.GetUsageAsync(organization);

        projectUsage = await _usageService.GetUsageAsync(organization, project);

        Assert.Equal(totalToIncrement, organizationUsage.HourlyTotal);
        Assert.Equal(totalToIncrement, projectUsage.HourlyTotal);
        Assert.Equal(totalToIncrement, organizationUsage.MonthlyTotal);
        Assert.Equal(totalToIncrement, projectUsage.MonthlyTotal);
        Assert.Equal(20, organizationUsage.HourlyBlocked);
        Assert.Equal(20, projectUsage.HourlyBlocked);
        Assert.Equal(20, organizationUsage.MonthlyBlocked);
        Assert.Equal(20, projectUsage.MonthlyBlocked);
    }
        public async Task An_interval_can_be_specified_before_which_a_released_lease_will_be_granted_again()
        {
            var tally = new ConcurrentDictionary<string, int>();
            var distributor = CreateDistributor(waitInterval: TimeSpan.FromMilliseconds(5000)).Trace();
            var countdown = new AsyncCountdownEvent(10);

            distributor.OnReceive(async lease =>
            {
                tally.AddOrUpdate(lease.LeasableResource.Name,
                                  addValueFactory: s => 1,
                                  updateValueFactory: (s, v) => v + 1);
                countdown.Signal();
            });

            await distributor.Start();
            await countdown.WaitAsync().Timeout();
            await distributor.Stop();

            tally.Count.Should().Be(10);
            tally.Should().ContainKeys("1", "2", "3", "4", "5", "6", "7", "8", "9", "10");
            tally.Should().ContainValues(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
        }
        public async Task SuriveBadLine()
        {
            AsyncCountdownEvent   eventsReceived   = new AsyncCountdownEvent(5);
            AsyncManualResetEvent serverShutdown   = new AsyncManualResetEvent();
            AsyncManualResetEvent connectionClosed = new AsyncManualResetEvent();

            using (var server =
                       new MockKubeApiServer(
                           testOutput,
                           async httpContext =>
            {
                httpContext.Response.StatusCode = (int)HttpStatusCode.OK;
                httpContext.Response.ContentLength = null;

                await WriteStreamLine(httpContext, MockKubeApiServer.MockPodResponse);
                await WriteStreamLine(httpContext, MockBadStreamLine);
                await WriteStreamLine(httpContext, MockAddedEventStreamLine);
                await WriteStreamLine(httpContext, MockBadStreamLine);
                await WriteStreamLine(httpContext, MockModifiedStreamLine);

                // make server alive, cannot set to int.max as of it would block response
                await serverShutdown.WaitAsync();
                return(false);
            }))
            {
                var client = new Kubernetes(new KubernetesClientConfiguration
                {
                    Host = server.Uri.ToString()
                });

                var listTask = await client.ListNamespacedPodWithHttpMessagesAsync("default", watch : true);

                var events = new HashSet <WatchEventType>();
                var errors = 0;

                var watcher = listTask.Watch <V1Pod, V1PodList>(
                    (type, item) =>
                {
                    testOutput.WriteLine($"Watcher received '{type}' event.");

                    events.Add(type);
                    eventsReceived.Signal();
                },
                    error =>
                {
                    testOutput.WriteLine($"Watcher received '{error.GetType().FullName}' error.");

                    errors += 1;
                    eventsReceived.Signal();
                },
                    onClosed: connectionClosed.Set
                    );

                // wait server yields all events
                await Task.WhenAny(eventsReceived.WaitAsync(), Task.Delay(TestTimeout));

                Assert.True(
                    eventsReceived.CurrentCount == 0,
                    "Timed out waiting for all events / errors to be received."
                    );

                Assert.Contains(WatchEventType.Added, events);
                Assert.Contains(WatchEventType.Modified, events);

                Assert.Equal(3, errors);

                Assert.True(watcher.Watching);

                // Let the server know it can initiate a shut down.
                serverShutdown.Set();

                await Task.WhenAny(connectionClosed.WaitAsync(), Task.Delay(TestTimeout));

                Assert.True(connectionClosed.IsSet);
            }
        }
        public async Task DisposeWatch()
        {
            var  connectionClosed = new AsyncManualResetEvent();
            var  eventsReceived   = new AsyncCountdownEvent(1);
            bool serverRunning    = true;

            using (var server = new MockKubeApiServer(testOutput, async httpContext =>
            {
                await WriteStreamLine(httpContext, MockKubeApiServer.MockPodResponse);

                while (serverRunning)
                {
                    await WriteStreamLine(httpContext, MockAddedEventStreamLine);
                }

                return(true);
            }))
            {
                var client = new Kubernetes(new KubernetesClientConfiguration
                {
                    Host = server.Uri.ToString()
                });

                var listTask = await client.ListNamespacedPodWithHttpMessagesAsync("default", watch : true);

                var events = new HashSet <WatchEventType>();

                var watcher = listTask.Watch <V1Pod, V1PodList>(
                    (type, item) =>
                {
                    events.Add(type);
                    eventsReceived.Signal();
                },
                    onClosed: connectionClosed.Set
                    );

                // wait at least an event
                await Task.WhenAny(eventsReceived.WaitAsync(), Task.Delay(TestTimeout));

                Assert.True(
                    eventsReceived.CurrentCount == 0,
                    "Timed out waiting for events."
                    );

                Assert.NotEmpty(events);
                Assert.True(watcher.Watching);

                watcher.Dispose();

                events.Clear();

                // Let the server disconnect
                serverRunning = false;

                var timeout = Task.Delay(TestTimeout);

                while (!timeout.IsCompleted && watcher.Watching)
                {
                    await Task.Yield();
                }

                Assert.Empty(events);
                Assert.False(watcher.Watching);
                Assert.True(connectionClosed.IsSet);
            }
        }
        public async Task DirectWatchEventsWithTimeout()
        {
            AsyncCountdownEvent   eventsReceived = new AsyncCountdownEvent(4);
            AsyncManualResetEvent serverShutdown = new AsyncManualResetEvent();

            using (var server = new MockKubeApiServer(testOutput, async httpContext =>
            {
                await Task.Delay(TimeSpan.FromSeconds(120)); // The default timeout is 100 seconds
                await WriteStreamLine(httpContext, MockAddedEventStreamLine);
                await WriteStreamLine(httpContext, MockDeletedStreamLine);
                await WriteStreamLine(httpContext, MockModifiedStreamLine);
                await WriteStreamLine(httpContext, MockErrorStreamLine);

                // make server alive, cannot set to int.max as of it would block response
                await serverShutdown.WaitAsync();
                return(false);
            }))
            {
                var client = new Kubernetes(new KubernetesClientConfiguration
                {
                    Host = server.Uri.ToString()
                });

                var events = new HashSet <WatchEventType>();
                var errors = 0;

                var watcher = await client.WatchNamespacedPodAsync(
                    name : "myPod",
                    @namespace : "default",
                    onEvent :
                    (type, item) =>
                {
                    testOutput.WriteLine($"Watcher received '{type}' event.");

                    events.Add(type);
                    eventsReceived.Signal();
                },
                    onError :
                    error =>
                {
                    testOutput.WriteLine($"Watcher received '{error.GetType().FullName}' error.");

                    errors += 1;
                    eventsReceived.Signal();
                }
                    );

                // wait server yields all events
                await Task.WhenAny(eventsReceived.WaitAsync(), Task.Delay(TestTimeout));

                Assert.True(
                    eventsReceived.CurrentCount == 0,
                    "Timed out waiting for all events / errors to be received."
                    );

                Assert.Contains(WatchEventType.Added, events);
                Assert.Contains(WatchEventType.Deleted, events);
                Assert.Contains(WatchEventType.Modified, events);
                Assert.Contains(WatchEventType.Error, events);

                Assert.Equal(0, errors);

                Assert.True(watcher.Watching);

                serverShutdown.Set();
            }
        }
Esempio n. 30
0
        public async Task CanIncrementSuspendedOrganizationUsageAsync()
        {
            var messageBus = GetService <IMessageBus>();

            var countdown = new AsyncCountdownEvent(2);
            await messageBus.SubscribeAsync <PlanOverage>(po => {
                _logger.Info($"Plan Overage for {po.OrganizationId} (Hourly: {po.IsHourly}");
                countdown.Signal();
            });

            var o = await _organizationRepository.AddAsync(new Organization { Name = "Test", MaxEventsPerMonth = 750, PlanId = BillingManager.SmallPlan.Id }, opt => opt.Cache());

            var project = await _projectRepository.AddAsync(new Project { Name = "Test", OrganizationId = o.Id, NextSummaryEndOfDayTicks = SystemClock.UtcNow.Ticks }, opt => opt.Cache());

            Assert.False(await _usageService.IncrementUsageAsync(o.Id, project.Id, false, 5));

            await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

            Assert.Equal(2, countdown.CurrentCount);
            Assert.Equal(5, await _cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id), 0));
            Assert.Equal(5, await _cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id, project.Id), 0));
            Assert.Equal(5, await _cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id), 0));
            Assert.Equal(5, await _cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id, project.Id), 0));
            Assert.Equal(0, await _cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(0, await _cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id, project.Id), 0));
            Assert.Equal(0, await _cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(0, await _cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id, project.Id), 0));

            o.IsSuspended       = true;
            o.SuspendedByUserId = TestConstants.UserId;
            o.SuspensionDate    = SystemClock.UtcNow;
            o.SuspensionCode    = SuspensionCode.Billing;
            o = await _organizationRepository.SaveAsync(o, opt => opt.Cache());

            Assert.True(await _usageService.IncrementUsageAsync(o.Id, project.Id, false, 4995));

            await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

            Assert.Equal(1, countdown.CurrentCount);
            Assert.Equal(5000, await _cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id), 0));
            Assert.Equal(5000, await _cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id, project.Id), 0));
            Assert.Equal(5000, await _cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id), 0));
            Assert.Equal(5000, await _cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id, project.Id), 0));
            Assert.Equal(4995, await _cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(4995, await _cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id, project.Id), 0));
            Assert.Equal(4995, await _cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(4995, await _cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id, project.Id), 0));

            o.RemoveSuspension();
            o = await _organizationRepository.SaveAsync(o, opt => opt.Cache());

            Assert.False(await _usageService.IncrementUsageAsync(o.Id, project.Id, false, 1));
            await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

            Assert.Equal(1, countdown.CurrentCount);
            Assert.Equal(5001, await _cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id), 0));
            Assert.Equal(5001, await _cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id, project.Id), 0));
            Assert.Equal(5001, await _cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id), 0));
            Assert.Equal(5001, await _cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id, project.Id), 0));
            Assert.Equal(4995, await _cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(4995, await _cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id, project.Id), 0));
            Assert.Equal(4995, await _cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(4995, await _cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id, project.Id), 0));
        }
Esempio n. 31
0
 public override Task Invoke(IncomingLogicalContext context, Func <Task> next)
 {
     context.Message.Instance.ToString().Output();
     countdown.Signal();
     return(next());
 }
Esempio n. 32
0
        public async Task CanIncrementUsageAsync()
        {
            var messageBus = GetService <IMessageBus>();

            var countdown = new AsyncCountdownEvent(2);
            await messageBus.SubscribeAsync <PlanOverage>(po => {
                _logger.Info($"Plan Overage for {po.OrganizationId} (Hourly: {po.IsHourly})");
                countdown.Signal();
            });

            var o = await _organizationRepository.AddAsync(new Organization { Name = "Test", MaxEventsPerMonth = 750, PlanId = BillingManager.SmallPlan.Id });

            var project = await _projectRepository.AddAsync(new Project { Name = "Test", OrganizationId = o.Id, NextSummaryEndOfDayTicks = SystemClock.UtcNow.Ticks }, opt => opt.Cache());

            await _configuration.Client.RefreshAsync(Indices.All);

            Assert.InRange(o.GetHourlyEventLimit(), 1, 750);

            int totalToIncrement = o.GetHourlyEventLimit() - 1;

            Assert.False(await _usageService.IncrementUsageAsync(o.Id, project.Id, false, totalToIncrement));
            await _configuration.Client.RefreshAsync(Indices.All);

            o = await _organizationRepository.GetByIdAsync(o.Id);

            await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

            Assert.Equal(2, countdown.CurrentCount);
            Assert.Equal(totalToIncrement, await _cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id), 0));
            Assert.Equal(totalToIncrement, await _cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id, project.Id), 0));
            Assert.Equal(totalToIncrement, await _cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id), 0));
            Assert.Equal(totalToIncrement, await _cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id, project.Id), 0));
            Assert.Equal(0, await _cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(0, await _cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id, project.Id), 0));
            Assert.Equal(0, await _cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(0, await _cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id, project.Id), 0));

            Assert.True(await _usageService.IncrementUsageAsync(o.Id, project.Id, false, 2));
            await _configuration.Client.RefreshAsync(Indices.All);

            o = await _organizationRepository.GetByIdAsync(o.Id);

            await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

            Assert.Equal(1, countdown.CurrentCount);
            Assert.Equal(totalToIncrement + 2, await _cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id), 0));
            Assert.Equal(totalToIncrement + 2, await _cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id, project.Id), 0));
            Assert.Equal(totalToIncrement + 2, await _cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id), 0));
            Assert.Equal(totalToIncrement + 2, await _cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id, project.Id), 0));
            Assert.Equal(1, await _cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(1, await _cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id, project.Id), 0));
            Assert.Equal(1, await _cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(1, await _cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id, project.Id), 0));

            o = await _organizationRepository.AddAsync(new Organization { Name = "Test", MaxEventsPerMonth = 750, PlanId = BillingManager.SmallPlan.Id });

            project = await _projectRepository.AddAsync(new Project { Name = "Test", OrganizationId = o.Id, NextSummaryEndOfDayTicks = SystemClock.UtcNow.Ticks }, opt => opt.Cache());

            await _configuration.Client.RefreshAsync(Indices.All);

            await _cache.RemoveAllAsync();

            totalToIncrement = o.GetHourlyEventLimit() + 20;
            Assert.True(await _usageService.IncrementUsageAsync(o.Id, project.Id, false, totalToIncrement));

            await countdown.WaitAsync(TimeSpan.FromMilliseconds(150));

            Assert.Equal(0, countdown.CurrentCount);
            Assert.Equal(totalToIncrement, await _cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id), 0));
            Assert.Equal(totalToIncrement, await _cache.GetAsync <long>(GetHourlyTotalCacheKey(o.Id, project.Id), 0));
            Assert.Equal(totalToIncrement, await _cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id), 0));
            Assert.Equal(totalToIncrement, await _cache.GetAsync <long>(GetMonthlyTotalCacheKey(o.Id, project.Id), 0));
            Assert.Equal(20, await _cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(20, await _cache.GetAsync <long>(GetHourlyBlockedCacheKey(o.Id, project.Id), 0));
            Assert.Equal(20, await _cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id), 0));
            Assert.Equal(20, await _cache.GetAsync <long>(GetMonthlyBlockedCacheKey(o.Id, project.Id), 0));
        }
Esempio n. 33
0
        public virtual async Task CanReceiveMessagesConcurrentlyAsync()
        {
            const int iterations = 100;
            var       messageBus = GetMessageBus();

            if (messageBus == null)
            {
                return;
            }

            var messageBuses = new List <IMessageBus>(10);

            try {
                var countdown = new AsyncCountdownEvent(iterations * 10);
                await Run.InParallelAsync(10, async i => {
                    var bus = GetMessageBus();
                    await bus.SubscribeAsync <SimpleMessageA>(msg => {
                        Assert.Equal("Hello", msg.Data);
                        countdown.Signal();
                    });

                    messageBuses.Add(bus);
                });

                var subscribe = Run.InParallelAsync(iterations,
                                                    i => {
#pragma warning disable AsyncFixer02 // Long running or blocking operations under an async method
                    SystemClock.Sleep(RandomData.GetInt(0, 10));
#pragma warning restore AsyncFixer02 // Long running or blocking operations under an async method
                    return(messageBuses.Random().SubscribeAsync <NeverPublishedMessage>(msg => Task.CompletedTask));
                });

                var publish = Run.InParallelAsync(iterations + 3, i => {
                    switch (i)
                    {
                    case 1:
                        return(messageBus.PublishAsync(new DerivedSimpleMessageA {
                            Data = "Hello"
                        }));

                    case 2:
                        return(messageBus.PublishAsync(new Derived2SimpleMessageA {
                            Data = "Hello"
                        }));

                    case 3:
                        return(messageBus.PublishAsync(new Derived3SimpleMessageA {
                            Data = "Hello"
                        }));

                    case 4:
                        return(messageBus.PublishAsync(new Derived4SimpleMessageA {
                            Data = "Hello"
                        }));

                    case 5:
                        return(messageBus.PublishAsync(new Derived5SimpleMessageA {
                            Data = "Hello"
                        }));

                    case 6:
                        return(messageBus.PublishAsync(new Derived6SimpleMessageA {
                            Data = "Hello"
                        }));

                    case 7:
                        return(messageBus.PublishAsync(new Derived7SimpleMessageA {
                            Data = "Hello"
                        }));

                    case 8:
                        return(messageBus.PublishAsync(new Derived8SimpleMessageA {
                            Data = "Hello"
                        }));

                    case 9:
                        return(messageBus.PublishAsync(new Derived9SimpleMessageA {
                            Data = "Hello"
                        }));

                    case 10:
                        return(messageBus.PublishAsync(new Derived10SimpleMessageA {
                            Data = "Hello"
                        }));

                    case iterations + 1:
                        return(messageBus.PublishAsync(new { Data = "Hello" }));

                    case iterations + 2:
                        return(messageBus.PublishAsync(new SimpleMessageC {
                            Data = "Hello"
                        }));

                    case iterations + 3:
                        return(messageBus.PublishAsync(new SimpleMessageB {
                            Data = "Hello"
                        }));

                    default:
                        return(messageBus.PublishAsync(new SimpleMessageA {
                            Data = "Hello"
                        }));
                    }
                });

                await Task.WhenAll(subscribe, publish);

                await countdown.WaitAsync(TimeSpan.FromSeconds(2));

                Assert.Equal(0, countdown.CurrentCount);
            } finally {
                foreach (var mb in messageBuses)
                {
                    await CleanupMessageBusAsync(mb);
                }

                await CleanupMessageBusAsync(messageBus);
            }
        }
        public async Task When_receiver_throws_then_work_distribution_continues()
        {
            var received = 0;
            var distributor = CreateDistributor(waitInterval: TimeSpan.FromMilliseconds(100)).Trace();
            var countdown = new AsyncCountdownEvent(20);

            distributor.OnReceive(async lease =>
            {
                Interlocked.Increment(ref received);

                if (received < 10)
                {
                    throw new Exception("dangit!");
                }

                countdown.Signal();
            });

            await distributor.Start();
            await countdown.WaitAsync().Timeout();
            await distributor.Stop();

            received.Should().BeGreaterOrEqualTo(20);
        }