Exemplo n.º 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);
        }
Exemplo n.º 2
0
        private void OnTopicMessage(RedisChannel redisChannel, RedisValue redisValue)
        {
            _logger.Trace("Queue OnMessage {0}: {1}", _queueName, redisValue);

            using (_monitor.Enter())
                _monitor.Pulse();
        }
Exemplo n.º 3
0
        private async Task OnTopicMessage(RedisChannel redisChannel, RedisValue redisValue)
        {
            _logger.Trace("Queue OnMessage {0}: {1}", _queueName, redisValue);

            using (await _monitor.EnterAsync())
                _monitor.Pulse();
        }
Exemplo n.º 4
0
        private async void OnTopicMessage(RedisChannel redisChannel, RedisValue redisValue)
        {
            _logger.Trace("Queue OnMessage {0}: {1}", _queueName, redisValue);

            // Note: The sync version can and will block the calling thread.
            using (await _monitor.EnterAsync().AnyContext())
                _monitor.Pulse();
        }
Exemplo n.º 5
0
 /// <summary>
 /// Adds the item to the items this is enumerating on.
 /// Will immediately release a waiting thread that can start working on itl
 /// </summary>
 /// <param name="item">The item.</param>
 public async Task AddItem(T item)
 {
     using (await monitor.EnterAsync())
     {
         cached.Enqueue(item);
         monitor.Pulse();
     }
 }
Exemplo n.º 6
0
        private async Task OnTopicMessage(RedisChannel redisChannel, RedisValue redisValue)
        {
#if DEBUG
            Logger.Trace().Message("Queue OnMessage {0}: {1}", _queueName, redisValue).Write();
#endif
            using (await _monitor.EnterAsync())
                _monitor.Pulse();
        }
Exemplo n.º 7
0
        /// <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();
            }
        }
Exemplo n.º 8
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;
            }));
        }
Exemplo n.º 9
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();
                }
            }
        }
Exemplo n.º 10
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);
            });
        }
Exemplo n.º 11
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();
                }
            }
        }
Exemplo n.º 12
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.º 13
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();
                }
            }
        }
Exemplo n.º 14
0
        public async Task Pulse_ReleasesOneWaiter()
        {
            AsyncMonitor monitor = new AsyncMonitor();

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

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

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

            Assert.Equal(1, result);
        }
Exemplo n.º 15
0
        public async Task Pulse_ReleasesOneWaiter()
        {
            var monitor    = new AsyncMonitor();
            int completed  = 0;
            var task1Ready = TaskCompletionSourceExtensions.CreateAsyncTaskSource <object>();
            var task2Ready = TaskCompletionSourceExtensions.CreateAsyncTaskSource <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);
        }
Exemplo n.º 16
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.º 17
0
        private async Task JobFiber(CancellationToken cancellationToken)
        {
            try {
                var headers = new Metadata {
                    { ProtocolConstants.AgentKeyHeaderName, apiKey }
                };
                using var stream = buildServer.acceptBuildJob(headers, null, cancellationToken);


                var buildTask = await ReadBuildTask(stream, cancellationToken);

                if (buildTask == null)
                {
                    return;
                }


                await using var buildDir = DirectoryCleanup.CreateTempDir(workspacesDir);
                logger.LogInformation("Created workspace for build: {0}, exists: {1}", buildDir.Value, Directory.Exists(buildDir.Value));
                var buildRunner = new BuildJobRunner(logger, buildDir.Value, stream.ResponseStream, stream.RequestStream, cancellationToken);
                await buildRunner.RunJob(buildTask);

                await ProcessArtifacts(stream, buildRunner, cancellationToken);
            }
            catch (OperationCanceledException) { }
            catch (Exception ex) {
                logger.LogError(ex, "Error running build job");
                await Task.Delay(1000, cancellationToken);
            }
            finally {
                using (await jobLock.EnterAsync(cancellationToken)) {
                    --runningJobs;
                    jobLock.Pulse();
                }
            }
        }
Exemplo n.º 18
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");
                }
            }
        }