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); }
private void OnTopicMessage(RedisChannel redisChannel, RedisValue redisValue) { _logger.Trace("Queue OnMessage {0}: {1}", _queueName, redisValue); using (_monitor.Enter()) _monitor.Pulse(); }
private async Task OnTopicMessage(RedisChannel redisChannel, RedisValue redisValue) { _logger.Trace("Queue OnMessage {0}: {1}", _queueName, redisValue); using (await _monitor.EnterAsync()) _monitor.Pulse(); }
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(); }
/// <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(); } }
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(); }
/// <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(); } }
/// <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; })); }
// 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(); } } }
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); }); }
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 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); }); }
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() { 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); }
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); }
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); }
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(); } } }
/// <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"); } } }