Exemplo n.º 1
0
        public void PulseAll_ReleasesAllWaiters()
        {
            AsyncContext.Run(async() =>
            {
                var monitor    = new AsyncMonitor();
                int completed  = 0;
                var task1Ready = new TaskCompletionSource();
                var task2Ready = new TaskCompletionSource();
                Task <IDisposable> lockTask1 = null;
                Task waitTask1 = null;
                var task1      = Task.Run(async() =>
                {
                    lockTask1 = monitor.EnterAsync();
                    using (await lockTask1)
                    {
                        waitTask1 = monitor.WaitAsync();
                        task1Ready.SetResult();
                        await waitTask1;
                        Interlocked.Increment(ref completed);
                    }
                });
                await task1Ready.Task;
                Task <IDisposable> lockTask2 = null;
                Task waitTask2 = null;
                var task2      = Task.Run(async() =>
                {
                    lockTask2 = monitor.EnterAsync();
                    using (await lockTask2)
                    {
                        waitTask2 = monitor.WaitAsync();
                        task2Ready.SetResult();
                        await waitTask2;
                        Interlocked.Increment(ref completed);
                    }
                });
                await task2Ready.Task;

                var lockTask3 = monitor.EnterAsync();
                using (await lockTask3)
                {
                    monitor.PulseAll();
                }
                await Task.WhenAll(task1, task2);
                var result = Interlocked.CompareExchange(ref completed, 0, 0);

                Assert.AreEqual(2, result);
            });
        }
Exemplo n.º 2
0
 public async Task ProcessingRpcCompleted()
 {
     using (await netChMonitor.EnterAsync())
     {
         await netChMonitor.WaitAsync();
     }
 }
Exemplo n.º 3
0
 public async Task AddingTransactionsCompleted()
 {
     using (await submitChMonitor.EnterAsync())
     {
         await submitChMonitor.WaitAsync();
     }
 }
Exemplo n.º 4
0
 public async Task CommitBlocksCompleted()
 {
     using (await commitChMonitor.EnterAsync())
     {
         await commitChMonitor.WaitAsync();
     }
 }
Exemplo n.º 5
0
        /// <summary>
        /// Wait for the model to be fully updated from RepRapFirmware
        /// </summary>
        /// <param name="cancellationToken">Cancellation token</param>
        /// <returns>Asynchronous task</returns>
        public static async Task WaitForFullUpdate(CancellationToken cancellationToken)
        {
            using (await _monitor.EnterAsync(cancellationToken))
            {
                await _monitor.WaitAsync(cancellationToken);

                Program.CancelSource.Token.ThrowIfCancellationRequested();
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Wait for the model to be fully updated from RepRapFirmware
        /// </summary>
        /// <returns>Asynchronous task</returns>
        public static async Task WaitForFullUpdate()
        {
            using (await _updateEvent.EnterAsync())
            {
                await _updateEvent.WaitAsync(Program.CancelSource.Token);

                Program.CancelSource.Token.ThrowIfCancellationRequested();
            }
        }
Exemplo n.º 7
0
        public async Task PulseAll_ReleasesAllWaiters()
        {
            AsyncMonitor monitor = new AsyncMonitor();

            int[] completed = { 0 };
            TaskCompletionSource <object> task1Ready = TaskCompletionSourceExtensions.CreateAsyncTaskSource <object>();
            TaskCompletionSource <object> task2Ready = TaskCompletionSourceExtensions.CreateAsyncTaskSource <object>();
            Task waitTask1 = null;
            Task task1     = Task.Run(async() =>
            {
                using (await monitor.EnterAsync())
                {
                    waitTask1 = monitor.WaitAsync();
                    task1Ready.SetResult(null);
                    await waitTask1;
                    Interlocked.Increment(ref completed[0]);
                }
            });
            await task1Ready.Task;
            Task waitTask2 = null;
            Task task2     = Task.Run(async() =>
            {
                using (await monitor.EnterAsync())
                {
                    waitTask2 = monitor.WaitAsync();
                    task2Ready.SetResult(null);
                    await waitTask2;
                    Interlocked.Increment(ref completed[0]);
                }
            });
            await task2Ready.Task;

            AwaitableDisposable <IDisposable> lockTask3 = monitor.EnterAsync();

            using (await lockTask3)
            {
                monitor.PulseAll();
            }
            await Task.WhenAll(task1, task2).ConfigureAwait(false);

            int result = Interlocked.CompareExchange(ref completed[0], 0, 0);

            Assert.Equal(2, result);
        }
Exemplo n.º 8
0
        public async Task PulseAll_ReleasesAllWaiters()
        {
            var  monitor    = new AsyncMonitor();
            int  completed  = 0;
            var  task1Ready = TaskCompletionSourceExtensions.CreateAsyncTaskSource <object>();
            var  task2Ready = TaskCompletionSourceExtensions.CreateAsyncTaskSource <object>();
            Task waitTask1  = null;
            var  task1      = Task.Run(async() =>
            {
                using (await monitor.EnterAsync())
                {
                    waitTask1 = monitor.WaitAsync();
                    task1Ready.SetResult(null);
                    await waitTask1;
                    Interlocked.Increment(ref completed);
                }
            });
            await task1Ready.Task;
            Task waitTask2 = null;
            var  task2     = Task.Run(async() =>
            {
                using (await monitor.EnterAsync())
                {
                    waitTask2 = monitor.WaitAsync();
                    task2Ready.SetResult(null);
                    await waitTask2;
                    Interlocked.Increment(ref completed);
                }
            });
            await task2Ready.Task;

            var lockTask3 = monitor.EnterAsync();

            using (await lockTask3)
            {
                monitor.PulseAll();
            }
            await Task.WhenAll(task1, task2);

            var result = Interlocked.CompareExchange(ref completed, 0, 0);

            Assert.Equal(2, result);
        }
Exemplo n.º 9
0
        public void Pulse_ReleasesOneWaiter()
        {
            Test.Async(async() =>
            {
                var monitor    = new AsyncMonitor();
                int completed  = 0;
                var task1Ready = new TaskCompletionSource();
                var task2Ready = new TaskCompletionSource();
                var task1      = TaskShim.Run(async() =>
                {
                    using (await monitor.EnterAsync())
                    {
                        var waitTask1 = monitor.WaitAsync();
                        task1Ready.SetResult();
                        await waitTask1;
                        Interlocked.Increment(ref completed);
                    }
                });
                await task1Ready.Task;
                var task2 = TaskShim.Run(async() =>
                {
                    using (await monitor.EnterAsync())
                    {
                        var waitTask2 = monitor.WaitAsync();
                        task2Ready.SetResult();
                        await waitTask2;
                        Interlocked.Increment(ref completed);
                    }
                });
                await task2Ready.Task;

                using (await monitor.EnterAsync())
                {
                    monitor.Pulse();
                }
                await TaskShim.WhenAny(task1, task2);
                var result = Interlocked.CompareExchange(ref completed, 0, 0);

                Assert.AreEqual(1, result);
            });
        }
Exemplo n.º 10
0
        public override async Task <IQueueEntry <T> > DequeueAsync(CancellationToken cancellationToken)
        {
            _logger.Trace("Queue {type} dequeuing item...", typeof(T).Name);
            _logger.Trace("Queue count: {0}", _queue.Count);

            if (_queue.Count == 0 && !cancellationToken.IsCancellationRequested)
            {
                _logger.Trace("Waiting to dequeue item...");
                var sw = Stopwatch.StartNew();

                try {
                    using (await _monitor.EnterAsync(cancellationToken))
                        await _monitor.WaitAsync(cancellationToken).AnyContext();
                } catch (TaskCanceledException) {}

                sw.Stop();
                _logger.Trace("Waited for dequeue: {0}", sw.Elapsed.ToString());
            }

            if (_queue.Count == 0)
            {
                return(null);
            }

            _logger.Trace("Dequeue: Attempt");

            QueueEntry <T> info;

            if (!_queue.TryDequeue(out info) || info == null)
            {
                return(null);
            }

            info.Attempts++;
            info.DequeuedTimeUtc = DateTime.UtcNow;

            if (!_dequeued.TryAdd(info.Id, info))
            {
                throw new ApplicationException("Unable to add item to the dequeued list.");
            }

            Interlocked.Increment(ref _dequeuedCount);
            _logger.Trace("Dequeue: Got Item");

            var entry = new QueueEntry <T>(info.Id, info.Value.Copy(), this, info.EnqueuedTimeUtc, info.Attempts);

            await OnDequeuedAsync(entry).AnyContext();

            ScheduleNextMaintenance(DateTime.UtcNow.Add(_workItemTimeout));

            return(entry);
        }
Exemplo n.º 11
0
        public async Task WillPulseMonitor()
        {
            var monitor = new AsyncMonitor();
            var sw      = Stopwatch.StartNew();

            // Monitor will not be pulsed and should be cancelled after 100ms.
            using (await monitor.EnterAsync())
                await Assert.ThrowsAsync <OperationCanceledException>(() => monitor.WaitAsync(TimeSpan.FromMilliseconds(100).ToCancellationToken()));
            sw.Stop();
            Assert.InRange(sw.ElapsedMilliseconds, 75, 125);

            var t = Task.Run(async() => {
                await SystemClock.SleepAsync(25);
                using (await monitor.EnterAsync())
                    monitor.Pulse();
            });

            sw = Stopwatch.StartNew();
            using (await monitor.EnterAsync())
                await monitor.WaitAsync(TimeSpan.FromSeconds(1).ToCancellationToken());
            sw.Stop();
            Assert.InRange(sw.ElapsedMilliseconds, 25, 100);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Process status updates in the background
        /// </summary>
        /// <returns>Asynchronous task</returns>
        public static async Task Run()
        {
            CancellationToken cancellationToken = Program.CancelSource.Token;

            do
            {
                // Wait for the next status response
                using (await _monitor.EnterAsync(cancellationToken))
                {
                    await _monitor.WaitAsync(cancellationToken);

                    cancellationToken.ThrowIfCancellationRequested();

                    // Process it
                    try
                    {
                        ReadOnlyMemory <byte> json = _json.AsMemory().Slice(0, _jsonLength);
                        switch (_module)
                        {
                        case 2:
                            await ProcessAdvancedResponse(json);

                            break;

                        case 3:
                            await ProcessPrintResponse(json);

                            break;

                        case 5:
                            await ProcessConfigResponse(json);

                            break;
                        }

                        // Notify waiting clients about the model update
                        if (_module == 2)
                        {
                            _updateEvent.PulseAll();
                        }
                    }
                    catch (JsonException e)
                    {
                        _logger.Error(e, "Failed to merge JSON (module {0})", _module);
                    }
                }
            }while (true);
        }
Exemplo n.º 13
0
        public async Task JobLoop(CancellationToken cancellationToken)
        {
            try {
                using (await jobLock.EnterAsync(cancellationToken)) {
                    while (!cancellationToken.IsCancellationRequested)
                    {
                        while (runningJobs < maxJobs)
                        {
                            _ = Task.Run(() => JobFiber(cancellationToken), cancellationToken);
                            ++runningJobs;
                        }

                        await jobLock.WaitAsync(cancellationToken);
                    }
                }
            }
            catch (OperationCanceledException) {}
        }
Exemplo n.º 14
0
        /// <summary>
        /// Advances the enumerator to the next element of the collection.
        /// </summary>
        /// <returns>
        /// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.
        /// </returns>
        /// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created. </exception>
        public async ValueTask <bool> MoveNextAsync()
        {
            using (await monitor.EnterAsync())
            {
                while (cached.Count == 0 && active)
                {
                    await monitor.WaitAsync();
                }

                if (active == false && cached.Count == 0)
                {
                    return(false);
                }

                current = cached.Dequeue();

                return(true);
            }
        }
        ///    <summary>
        ///    MoveNext the enumerator
        ///    </summary>
        ///    <returns></returns>
        public async ValueTask <bool> MoveNextAsync()
        {
            using (await monitor.EnterAsync())
            {
                if (Interlocked.Increment(ref callsToMoveNext) == numberOfConsumers)
                {
                    callsToMoveNext = 0;
                    moveNext        = await innerEnumerator.MoveNextAsync();

                    current = innerEnumerator.Current;

                    Debug("Pulsing all waiting threads");

                    monitor.PulseAll();
                }
                else
                {
                    await monitor.WaitAsync();
                }
            }
            return(moveNext);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Waits for commands to be received and enqueues them in a concurrent queue so that a <see cref="Code"/>
        /// can decide when to cancel/resume/resolve the execution.
        /// </summary>
        /// <returns>Task that represents the lifecycle of the connection</returns>
        public override async Task Process()
        {
            lock (_connections[_mode])
            {
                _connections[_mode].Add(this);
            }
            Connection.Logger.Debug("Interception processor registered");

            using (await _codeMonitor.EnterAsync(Program.CancellationToken))
            {
                try
                {
                    do
                    {
                        // Wait for the next code to be intercepted
                        do
                        {
                            using CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(Program.CancellationToken);
                            cts.CancelAfter(Settings.SocketPollInterval);

                            try
                            {
                                await _codeMonitor.WaitAsync(Program.CancellationToken);

                                break;
                            }
                            catch (OperationCanceledException)
                            {
                                if (Program.CancellationToken.IsCancellationRequested)
                                {
                                    throw;
                                }
                                Connection.Poll();
                            }
                        }while (true);

                        try
                        {
                            // Send it to the client
                            await Connection.Send(_codeBeingIntercepted);

                            // Keep processing incoming commands until a final action for the code has been received
                            BaseCommand command;
                            Type        commandType;
                            do
                            {
                                // Read another command from the IPC connection
                                command = await Connection.ReceiveCommand();

                                commandType = command.GetType();
                                if (Command.SupportedCommands.Contains(commandType))
                                {
                                    // Make sure it is permitted
                                    Connection.CheckPermissions(commandType);

                                    // Execute regular commands here
                                    object result = await command.Invoke();

                                    await Connection.SendResponse(result);
                                }
                                else if (SupportedCommands.Contains(commandType))
                                {
                                    // Make sure it is permitted
                                    Connection.CheckPermissions(commandType);

                                    // Send other commands to the task intercepting the code
                                    _interceptionResult = command;
                                    _codeMonitor.Pulse();
                                    break;
                                }
                                else
                                {
                                    // Take care of unsupported commands
                                    throw new ArgumentException($"Invalid command {command.Command} (wrong mode?)");
                                }
                            }while (!Program.CancellationToken.IsCancellationRequested);

                            // Stop if the connection has been terminated
                            if (command == null)
                            {
                                break;
                            }
                        }
                        catch (SocketException)
                        {
                            // Client has closed the connection while we're waiting for a result. Carry on...
                            _interceptionResult = null;
                            _codeMonitor.Pulse();
                            throw;
                        }
                    }while (!Program.CancellationToken.IsCancellationRequested);
                }
                finally
                {
                    lock (_connections[_mode])
                    {
                        _connections[_mode].Remove(this);
                    }
                    Connection.Logger.Debug("Interception processor unregistered");
                }
            }
        }
Exemplo n.º 17
0
        protected override async Task <IQueueEntry <T> > DequeueImplAsync(CancellationToken cancellationToken)
        {
            _logger.Trace("Queue {_queueName} dequeuing item...", _queueName);
            var now = SystemClock.UtcNow.Ticks;

            await EnsureMaintenanceRunningAsync().AnyContext();
            await EnsureTopicSubscriptionAsync().AnyContext();

            var linkedCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(_queueDisposedCancellationTokenSource.Token, cancellationToken).Token;

            RedisValue value = await DequeueIdAsync(linkedCancellationToken).AnyContext();

            if (linkedCancellationToken.IsCancellationRequested && value.IsNullOrEmpty)
            {
                return(null);
            }

            _logger.Trace("Initial list value: {0}", (value.IsNullOrEmpty ? "<null>" : value.ToString()));

            while (value.IsNullOrEmpty && !linkedCancellationToken.IsCancellationRequested)
            {
                _logger.Trace("Waiting to dequeue item...");
                var sw = Stopwatch.StartNew();

                try {
                    using (await _monitor.EnterAsync(cancellationToken).AnyContext())
                        await _monitor.WaitAsync(cancellationToken).AnyContext();
                } catch (OperationCanceledException) { }

                sw.Stop();
                _logger.Trace("Waited for dequeue: {0}", sw.Elapsed.ToString());

                value = await DequeueIdAsync(linkedCancellationToken).AnyContext();

                _logger.Trace("List value: {0}", (value.IsNullOrEmpty ? "<null>" : value.ToString()));
            }

            if (value.IsNullOrEmpty)
            {
                return(null);
            }

            await Run.WithRetriesAsync(() => _cache.SetAsync(GetDequeuedTimeKey(value), now, GetWorkItemTimeoutTimeTtl()), logger : _logger).AnyContext();

            await Run.WithRetriesAsync(() => _cache.SetAsync(GetRenewedTimeKey(value), now, GetWorkItemTimeoutTimeTtl()), logger : _logger).AnyContext();

            try {
                var entry = await GetQueueEntryAsync(value).AnyContext();

                if (entry == null)
                {
                    return(null);
                }

                Interlocked.Increment(ref _dequeuedCount);
                await OnDequeuedAsync(entry).AnyContext();

                _logger.Debug("Dequeued item: {0}", value);

                return(entry);
            } catch (Exception ex) {
                _logger.Error(ex, "Error getting dequeued item payload: {0}", value);
                throw;
            }
        }
Exemplo n.º 18
0
        public override async Task <QueueEntry <T> > DequeueAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
#if DEBUG
            Logger.Trace().Message($"Queue {_queueName} dequeuing item...").Write();
#endif
            await EnsureMaintenanceRunningAsync().AnyContext();
            await EnsureTopicSubscriptionAsync().AnyContext();

            var linkedCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(_queueDisposedCancellationTokenSource.Token, cancellationToken).Token;

            RedisValue value = await GetRedisValueAsync(linkedCancellationToken).AnyContext();

            if (linkedCancellationToken.IsCancellationRequested && value.IsNullOrEmpty)
            {
                return(null);
            }
#if DEBUG
            Logger.Trace().Message("Initial list value: {0}", (value.IsNullOrEmpty ? "<null>" : value.ToString())).Write();
#endif
            while (value.IsNullOrEmpty && !linkedCancellationToken.IsCancellationRequested)
            {
#if DEBUG
                Logger.Trace().Message("Waiting to dequeue item...").Write();
                var sw = Stopwatch.StartNew();
#endif
                try {
                    using (await _monitor.EnterAsync(cancellationToken))
                        await _monitor.WaitAsync(cancellationToken).AnyContext();
                } catch (TaskCanceledException) { }
#if DEBUG
                sw.Stop();
                Logger.Trace().Message("Waited for dequeue: {0}", sw.Elapsed.ToString()).Write();
#endif
                value = await GetRedisValueAsync(linkedCancellationToken).AnyContext();

#if DEBUG
                Logger.Trace().Message("List value: {0}", (value.IsNullOrEmpty ? "<null>" : value.ToString())).Write();
#endif
            }

            if (value.IsNullOrEmpty)
            {
                return(null);
            }

            await _cache.SetAsync(GetDequeuedTimeKey(value), DateTime.UtcNow.Ticks, GetDequeuedTimeTtl()).AnyContext();

            try {
                var payload = await _cache.GetAsync <T>(GetPayloadKey(value)).AnyContext();

                if (payload.IsNull)
                {
                    Logger.Error().Message("Error getting queue payload: {0}", value).Write();
                    await _db.ListRemoveAsync(WorkListName, value).AnyContext();

                    return(null);
                }

                var enqueuedTimeTicks = await _cache.GetAsync <long>(GetEnqueuedTimeKey(value), 0).AnyContext();

                var attemptsValue = await _cache.GetAsync <int>(GetAttemptsKey(value), -1).AnyContext();

                var entry = new QueueEntry <T>(value, payload.Value, this, new DateTime(enqueuedTimeTicks, DateTimeKind.Utc), attemptsValue);
                Interlocked.Increment(ref _dequeuedCount);
                await OnDequeuedAsync(entry).AnyContext();

#if DEBUG
                Logger.Debug().Message("Dequeued item: {0}", value).Write();
#endif
                return(entry);
            } catch (Exception ex) {
                Logger.Error().Exception(ex).Message("Error getting queue payload: {0}", value).Write();
                throw;
            }
        }