Beispiel #1
0
        public override async Task <string> EnqueueAsync(T data)
        {
            string id = Guid.NewGuid().ToString("N");

            _logger.Trace("Queue {0} enqueue item: {1}", typeof(T).Name, id);

            if (!await OnEnqueuingAsync(data).AnyContext())
            {
                return(null);
            }

            var entry = new QueueEntry <T>(id, data.Copy(), this, DateTime.UtcNow, 0);

            _queue.Enqueue(entry);
            _logger.Trace("Enqueue: Set Event");

            using (await _monitor.EnterAsync())
                _monitor.Pulse();
            Interlocked.Increment(ref _enqueuedCount);

            await OnEnqueuedAsync(entry).AnyContext();

            _logger.Trace("Enqueue done");

            return(id);
        }
Beispiel #2
0
        public void Locked_PreventsLockUntilUnlocked()
        {
            AsyncContext.Run(async() =>
            {
                var monitor       = new AsyncMonitor();
                var task1HasLock  = new TaskCompletionSource();
                var task1Continue = new TaskCompletionSource();
                Task <IDisposable> initialLockTask = null;

                var task1 = Task.Run(async() =>
                {
                    initialLockTask = monitor.EnterAsync();
                    using (await initialLockTask)
                    {
                        task1HasLock.SetResult();
                        await task1Continue.Task;
                    }
                });
                await task1HasLock.Task;

                var lockTask = monitor.EnterAsync();
                Assert.IsFalse(lockTask.IsCompleted);
                task1Continue.SetResult();
                await lockTask;
            });
        }
        /// <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();
            }
        }
        /// <summary>
        /// Merge a received status response into the object model
        /// </summary>
        /// <param name="module">Module that is supposed to be merged</param>
        /// <param name="json">JSON data</param>
        /// <returns>Asynchronous task</returns>
        public static async Task ProcessResponse(byte module, Memory <byte> json)
        {
            using (await _monitor.EnterAsync(Program.CancelSource.Token))
            {
                _module = module;
                json.CopyTo(_json);
                _jsonLength = json.Length;

                _monitor.Pulse();
            }
        }
Beispiel #5
0
        // Background work

        private async Task ProcessingRpc(CancellationToken ct)
        {
            while (!ct.IsCancellationRequested)
            {
                var rpc = await netCh.DequeueAsync(ct);

                logger.Debug("Processing RPC");
                await ProcessRpcAsync(rpc, ct);

                using (await netChMonitor.EnterAsync())
                {
                    netChMonitor.Pulse();
                }
            }
        }
Beispiel #6
0
        public void Pulse_ReleasesOneWaiter()
        {
            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;

                Task <IDisposable> lockTask3 = monitor.EnterAsync();
                using (await lockTask3)
                {
                    monitor.Pulse();
                }
                await Task.WhenAny(task1, task2);
                var result = Interlocked.CompareExchange(ref completed, 0, 0);

                Assert.AreEqual(1, result);
            });
        }
        public async Task Unlocked_PermitsLock()
        {
            var monitor = new AsyncMonitor();

            var   task = monitor.EnterAsync();
            await task;
        }
Beispiel #8
0
        private async Task AddingTransactions(CancellationToken ct)

        {
            while (!ct.IsCancellationRequested)
            {
                var tx = await submitCh.DequeueAsync(ct);

                logger.Debug("Adding Transaction");
                await AddTransaction(tx, ct);

                using (await submitChMonitor.EnterAsync())
                {
                    submitChMonitor.Pulse();
                }
            }
        }
        public async Task Unlocked_PermitsLock()
        {
            AsyncMonitor monitor = new AsyncMonitor();

            AwaitableDisposable <IDisposable> task = monitor.EnterAsync();
            await task;
        }
Beispiel #10
0
 public async Task CommitBlocksCompleted()
 {
     using (await commitChMonitor.EnterAsync())
     {
         await commitChMonitor.WaitAsync();
     }
 }
Beispiel #11
0
 public async Task AddingTransactionsCompleted()
 {
     using (await submitChMonitor.EnterAsync())
     {
         await submitChMonitor.WaitAsync();
     }
 }
        /// <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();
            }
        }
Beispiel #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) {}
        }
        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);
        }
        public void PulseAll_ReleasesAllWaiters()
        {
            Test.Async(async() =>
            {
                var monitor    = new AsyncMonitor();
                int completed  = 0;
                var task1Ready = new TaskCompletionSource();
                var task2Ready = new TaskCompletionSource();
                Task waitTask1 = null;
                var task1      = TaskShim.Run(async() =>
                {
                    using (await monitor.EnterAsync())
                    {
                        waitTask1 = monitor.WaitAsync();
                        task1Ready.SetResult();
                        await waitTask1;
                        Interlocked.Increment(ref completed);
                    }
                });
                await task1Ready.Task;
                Task waitTask2 = null;
                var task2      = TaskShim.Run(async() =>
                {
                    using (await monitor.EnterAsync())
                    {
                        waitTask2 = monitor.WaitAsync();
                        task2Ready.SetResult();
                        await waitTask2;
                        Interlocked.Increment(ref completed);
                    }
                });
                await task2Ready.Task;

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

                Assert.AreEqual(2, result);
            });
        }
        public void Unlocked_PermitsLock()
        {
            Test.Async(async() =>
            {
                var monitor = new AsyncMonitor();

                var task = monitor.EnterAsync();
                await task;
            });
        }
Beispiel #17
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);
            }
        }
        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);
        }
Beispiel #19
0
        public async Task <byte[]> GetRpcResultAsync(long callUid, CancellationToken token)
        {
            IDisposable monitor = null;

            try
            {
                monitor = await m_monitor.EnterAsync(token).ConfigureAwait(false);

                if (!m_blockingRpcCalls.Add(callUid))
                {
                    return(null);
                }
                for (;;)
                {
                    var    pair = new ImmutablePair <uint, uint>((uint)callUid >> 16, (uint)callUid & 0xffff);
                    byte[] str;
                    if (!m_rpcResults.TryGetValue(pair, out str))
                    {
                        if (m_terminating)
                        {
                            m_blockingRpcCalls.Remove(callUid);
                            return(null);
                        }

                        await m_monitor.WaitAsync(token).ConfigureAwait(false);

                        if (token.IsCancellationRequested)
                        {
                            m_blockingRpcCalls.Remove(callUid);
                            return(null);
                        }
                        if (m_terminating)
                        {
                            m_blockingRpcCalls.Remove(callUid);
                            return(null);
                        }
                        continue;
                    }
                    byte[] result = new byte[str.Length];
                    Array.Copy(str, result, result.Length);
                    m_blockingRpcCalls.Remove(callUid);
                    return(result);
                }
            }
            catch (OperationCanceledException)
            {
                // Operation canceled. Return null.
                return(null);
            }
            finally
            {
                monitor?.Dispose();
            }
        }
Beispiel #20
0
        private async Task CommitBlocks(CancellationToken ct)
        {
            while (!ct.IsCancellationRequested)
            {
                var block = await commitCh.DequeueAsync(ct);

                logger.Debug("Committing Block Index={Index}; RoundReceived={RoundReceived}; TxCount={TxCount}", block.Index(), block.RoundReceived(), block.Transactions().Length);

                var err = await Commit(block);

                if (err != null)
                {
                    logger.Error("Committing Block", err);
                }

                using (await commitChMonitor.EnterAsync())
                {
                    commitChMonitor.Pulse();
                }
            }
        }
        public async Task Pulse_ReleasesOneWaiter()
        {
            var monitor    = new AsyncMonitor();
            int completed  = 0;
            var task1Ready = new TaskCompletionSource <object>();
            var task2Ready = new TaskCompletionSource <object>();
            var task1      = Task.Run(async() =>
            {
                using (await monitor.EnterAsync())
                {
                    var waitTask1 = monitor.WaitAsync();
                    task1Ready.SetResult(null);
                    await waitTask1;
                    Interlocked.Increment(ref completed);
                }
            });
            await task1Ready.Task;
            var task2 = Task.Run(async() =>
            {
                using (await monitor.EnterAsync())
                {
                    var waitTask2 = monitor.WaitAsync();
                    task2Ready.SetResult(null);
                    await waitTask2;
                    Interlocked.Increment(ref completed);
                }
            });
            await task2Ready.Task;

            using (await monitor.EnterAsync())
            {
                monitor.Pulse();
            }
            await Task.WhenAny(task1, task2);

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

            Assert.Equal(1, result);
        }
        public async Task Locked_PreventsLockUntilUnlocked()
        {
            var monitor       = new AsyncMonitor();
            var task1HasLock  = TaskCompletionSourceExtensions.CreateAsyncTaskSource <object>();
            var task1Continue = TaskCompletionSourceExtensions.CreateAsyncTaskSource <object>();

            var task1 = Task.Run(async() =>
            {
                using (await monitor.EnterAsync())
                {
                    task1HasLock.SetResult(null);
                    await task1Continue.Task;
                }
            });
            await task1HasLock.Task;

            var lockTask = monitor.EnterAsync().AsTask();

            Assert.False(lockTask.IsCompleted);
            task1Continue.SetResult(null);
            await lockTask;
        }
Beispiel #23
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);
        }
Beispiel #24
0
        /// <summary>
        /// Executes this operation
        /// </summary>
        /// <param name="rows">The rows.</param>
        /// <param name="cancellationToken">A CancellationToken to stop execution</param>
        /// <returns></returns>
        public override IAsyncEnumerable <Row> Execute(IAsyncEnumerable <Row> rows, CancellationToken cancellationToken = default)
        {
            return(new AsyncEnumerable <Row>(yield => {
                var input = new GatedThreadSafeEnumerator <Row>(Operations.Count, rows, cancellationToken);

                AsyncMonitor monitor = new AsyncMonitor();

                Task[] tasks = Operations
                               .Select(async operation =>
                {
                    var clone = input.Select(r => r.Clone());
                    var result = operation.Execute(clone, cancellationToken);

                    if (result == null)
                    {
                        await input.DisposeAsync();
                        return null;
                    }

                    var enumerator = result.GetAsyncEnumerator(cancellationToken);

                    return Task.Run(async() =>
                    {
                        try
                        {
                            while (await enumerator.MoveNextAsync())
                            {
                                ;
                            }
                        }
                        finally
                        {
                            using (await monitor.EnterAsync(cancellationToken))
                            {
                                await enumerator.DisposeAsync();
                                monitor.Pulse();
                            }
                        }
                    }, cancellationToken);
                })
                               .Where(t => t?.Result != null)
                               .Select(t => t.Result)
                               .ToArray();

                Task.WaitAll(tasks);

                return Task.CompletedTask;
            }));
        }
        public void Locked_PreventsLockUntilUnlocked()
        {
            Test.Async(async() =>
            {
                var monitor       = new AsyncMonitor();
                var task1HasLock  = new TaskCompletionSource();
                var task1Continue = new TaskCompletionSource();

                var task1 = TaskShim.Run(async() =>
                {
                    using (await monitor.EnterAsync())
                    {
                        task1HasLock.SetResult();
                        await task1Continue.Task;
                    }
                });
                await task1HasLock.Task;

                var lockTask = monitor.EnterAsync().AsTask();
                Assert.IsFalse(lockTask.IsCompleted);
                task1Continue.SetResult();
                await lockTask;
            });
        }
Beispiel #26
0
 public async Task <bool> StopAsync()
 {
     using (await stopSync.EnterAsync())
         if (!end)
         {
             end     = true;
             awaiter = new TaskCompletionSource <bool>();
             bool result = await awaiter.Task;
             awaiter = null;
             return(result);
         }
         else
         {
             return(true);
         }
 }
Beispiel #27
0
        public async Task <IPipelineStatus> AddJobs(IPipelineRunManager pipelineRunManager, IEnumerable <BuildJob> jobs, int buildNum, CancellationToken cancellationToken)
        {
            var dependentJobs = new HashSet <BuildJob>();
            var jobMap        = new Dictionary <BuildJob, IJobStatus>();

            var runnableJobs = new List <RunnableJob>();

            foreach (var job in jobs)
            {
                AddBuildJob(pipelineRunManager, job, runnableJobs, dependentJobs, jobMap);
            }

            var jobIds = new HashSet <string>(jobMap.Count);

            foreach (var buildJob in jobMap.Keys)
            {
                if (!jobIds.Add(buildJob.Id))
                {
                    throw new Exception("Duplicate job id.");
                }
            }

            runnableJobs.Reverse();

            using (await monitor.EnterAsync(cancellationToken)) {
                foreach (var jobRun in runnableJobs)
                {
                    await jobRun.Status.WriteBuildJobFile();

                    jobQueue.AddLast(jobRun);
                }

                monitor.PulseAll();
            }

            return(new PipelineStatus(
                       new ReadOnlyDictionary <string, IJobStatus>(jobMap.ToDictionary(kvp => kvp.Key.Id, kvp => kvp.Value)),
                       buildNum,
                       pipelineRunManager.PipelineDir
                       ));
        }
        public async Task <byte[]> ReadAsync(string fileName)
        {
            if (_cache.ContainsKey(fileName))
            {
                return(_cache[fileName]);
            }

            using (await AsyncMonitor.EnterAsync(fileName))
            {
                // double check cache since it can be populated in another thread
                if (_cache.ContainsKey(fileName))
                {
                    return(_cache[fileName]);
                }

                var fileData = await _fileReader.ReadAsync(fileName);

                RealReadCallCount++;
                _cache[fileName] = fileData;
                return(fileData);
            }
        }
        ///    <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);
        }
Beispiel #30
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;
            }
        }