private async Task Execute()
        {
            try
            {
                var cancelToken = _cancellationTokenSource.Token;
                var opts        = new ExecutionDataflowBlockOptions()
                {
                    MaxDegreeOfParallelism = MaxConcurrentItems,
                    BoundedCapacity        = MaxConcurrentItems + 1
                };

                var actionBlock = new ActionBlock <string>(ExecuteItem, opts);

                while (!cancelToken.IsCancellationRequested)
                {
                    try
                    {
                        if (!SpinWait.SpinUntil(() => actionBlock.InputCount == 0, Options.IdleTime))
                        {
                            continue;
                        }

                        var item = await QueueProvider.DequeueWork(Queue, cancelToken);

                        if (item == null)
                        {
                            if (!QueueProvider.IsDequeueBlocking)
                            {
                                await Task.Delay(Options.IdleTime, cancelToken);
                            }
                            continue;
                        }

                        if (!actionBlock.Post(item))
                        {
                            await QueueProvider.QueueWork(item, Queue);
                        }
                    }
                    catch (OperationCanceledException ce)
                    {
                        Logger.LogError(ce.Message, ce);
                    }
                    catch (Exception ex)
                    {
                        Logger.LogError(ex.Message, ex);
                    }
                }

                actionBlock.Complete();
                await actionBlock.Completion;
            }
            catch (Exception ex)
            {
                Logger.LogError(ex.Message, ex);
                //This is to prevent async void crashing the program.
                //Should never reach this line
                //TODO remove async void
            }
        }
Example #2
0
        private async void RunEvents()
        {
            while (!_shutdown)
            {
                try
                {
                    var eventId = await _queueProvider.DequeueWork(QueueType.Event);

                    if (eventId != null)
                    {
                        if (await _lockProvider.AcquireLock($"evt:{eventId}"))
                        {
                            try
                            {
                                var evt = await _persistenceStore.GetEvent(eventId);

                                if (evt.EventTime <= DateTime.Now.ToUniversalTime())
                                {
                                    var subs = await _persistenceStore.GetSubcriptions(evt.EventName, evt.EventKey, evt.EventTime);

                                    var success = true;

                                    foreach (var sub in subs.ToList())
                                    {
                                        success = success && await SeedSubscription(evt, sub);
                                    }

                                    if (success)
                                    {
                                        await _persistenceStore.MarkEventProcessed(eventId);
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                _logger.LogError(ex.Message);
                            }
                            finally
                            {
                                await _lockProvider.ReleaseLock($"evt:{eventId}");
                            }
                        }
                        else
                        {
                            _logger.LogInformation($"Event locked {eventId}");
                        }
                    }
                    else
                    {
                        await Task.Delay(_options.IdleTime); //no work
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex.Message);
                }
            }
        }
Example #3
0
        private async void Execute()
        {
            var cancelToken  = _cancellationTokenSource.Token;
            var activeTasks  = new Dictionary <string, Task>();
            var secondPasses = new HashSet <string>();

            while (!cancelToken.IsCancellationRequested)
            {
                try
                {
                    if (activeTasks.Count >= MaxConcurrentItems)
                    {
                        await Task.Delay(Options.IdleTime);

                        continue;
                    }

                    var item = await QueueProvider.DequeueWork(Queue, cancelToken);

                    if (item == null)
                    {
                        if (!QueueProvider.IsDequeueBlocking)
                        {
                            await Task.Delay(Options.IdleTime, cancelToken);
                        }
                        continue;
                    }

                    if (activeTasks.ContainsKey(item))
                    {
                        secondPasses.Add(item);
                        if (!EnableSecondPasses)
                        {
                            await QueueProvider.QueueWork(item, Queue);
                        }
                        continue;
                    }

                    secondPasses.Remove(item);

                    var task = new Task(async(object data) =>
                    {
                        try
                        {
                            await ExecuteItem((string)data);
                            while (EnableSecondPasses && secondPasses.Contains(item))
                            {
                                secondPasses.Remove(item);
                                await ExecuteItem((string)data);
                            }
                        }
                        finally
                        {
                            lock (activeTasks)
                            {
                                activeTasks.Remove((string)data);
                            }
                        }
                    }, item);
                    lock (activeTasks)
                    {
                        activeTasks.Add(item, task);
                    }

                    task.Start();
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex, ex.Message);
                }
            }

            foreach (var task in activeTasks.Values)
            {
                task.Wait();
            }
        }
Example #4
0
        private async Task Execute()
        {
            var cancelToken = _cancellationTokenSource.Token;

            while (!cancelToken.IsCancellationRequested)
            {
                try
                {
                    var activeCount = 0;
                    lock (_activeTasks)
                    {
                        activeCount = _activeTasks.Count;
                    }
                    if (activeCount >= MaxConcurrentItems)
                    {
                        await Task.Delay(Options.IdleTime);

                        continue;
                    }

                    var item = await QueueProvider.DequeueWork(Queue, cancelToken);

                    if (item == null)
                    {
                        if (!QueueProvider.IsDequeueBlocking)
                        {
                            await Task.Delay(Options.IdleTime, cancelToken);
                        }
                        continue;
                    }

                    var hasTask = false;
                    lock (_activeTasks)
                    {
                        hasTask = _activeTasks.ContainsKey(item);
                    }
                    if (hasTask)
                    {
                        _secondPasses.Add(item);
                        if (!EnableSecondPasses)
                        {
                            await QueueProvider.QueueWork(item, Queue);
                        }
                        continue;
                    }

                    _secondPasses.TryRemove(item);

                    var waitHandle = new ManualResetEvent(false);
                    lock (_activeTasks)
                    {
                        _activeTasks.Add(item, waitHandle);
                    }
                    var task = ExecuteItem(item, waitHandle);
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex, ex.Message);
                }
            }

            List <EventWaitHandle> toComplete;

            lock (_activeTasks)
            {
                toComplete = _activeTasks.Values.ToList();
            }

            foreach (var handle in toComplete)
            {
                handle.WaitOne();
            }
        }
Example #5
0
        /// <summary>
        /// Worker thread body
        /// </summary>
        private async void RunWorkflows()
        {
            while (!_shutdown)
            {
                try
                {
                    var workflowId = await _queueProvider.DequeueWork(QueueType.Workflow);

                    if (workflowId != null)
                    {
                        try
                        {
                            if (await _lockProvider.AcquireLock(workflowId))
                            {
                                WorkflowInstance       workflow = null;
                                WorkflowExecutorResult result   = null;
                                try
                                {
                                    workflow = await _persistenceStore.GetWorkflowInstance(workflowId);

                                    if (workflow.Status == WorkflowStatus.Runnable)
                                    {
                                        try
                                        {
                                            result = _executor.Execute(workflow, _options);
                                        }
                                        finally
                                        {
                                            await _persistenceStore.PersistWorkflow(workflow);
                                        }
                                    }
                                }
                                finally
                                {
                                    await _lockProvider.ReleaseLock(workflowId);

                                    if ((workflow != null) && (result != null))
                                    {
                                        foreach (var sub in result.Subscriptions)
                                        {
                                            await SubscribeEvent(sub);
                                        }

                                        await _persistenceStore.PersistErrors(result.Errors);

                                        if ((workflow.Status == WorkflowStatus.Runnable) && workflow.NextExecution.HasValue && workflow.NextExecution.Value < DateTime.Now.ToUniversalTime().Ticks)
                                        {
                                            await _queueProvider.QueueWork(workflowId, QueueType.Workflow);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                _logger.LogInformation("Workflow locked {0}", workflowId);
                            }
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError(ex.Message);
                        }
                    }
                    else
                    {
                        await Task.Delay(_options.IdleTime);  //no work
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex.Message);
                }
            }
        }