public static async Task Go(DbConnection connection, EventQueueItem item, IServiceProvider provider, DbTransaction transaction) { var type = Type.GetType(item.Action); BaseTask resolved = null; try { if (type != null) { resolved = (BaseTask)ActivatorUtilities.CreateInstance(provider, type, item); await resolved.Go(); } await connection.ExecuteAsync("DELETE from \"EventQueue\" where \"Id\" = @Id", new { Id = item.Id }); transaction.Commit(); } catch (Exception e) { Console.WriteLine(e); // failed item.AttemptCount++; item.NextAttempt = resolved.NextTry(item.AttemptCount); transaction.Rollback(); await connection.ExecuteAsync("UPDATE \"EventQueue\" set \"AttemptCount\"=@AttemptCount, \"NextAttempt\"=@NextAttempt where \"Id\" = @Id", new { Attemptcount = item.AttemptCount, NextAttempt = item.NextAttempt, Id = item.Id }); } transaction.Dispose(); }
public async void _do() { await Task.Delay(2000); DateTime after = DateTime.MinValue; while (true) { // set up the wait _cancellationTokenSource?.Dispose(); _cancellationTokenSource = new CancellationTokenSource(); var sleepTime = await _getSleepTime(after); if (sleepTime != 0) { try { if (sleepTime > 0) { _cancellationTokenSource.CancelAfter(sleepTime); } await _notifier.Subscribe(BackgroundTaskPath, (a) => _cancellationTokenSource?.Cancel()); await _connection.WaitAsync(_cancellationTokenSource.Token); } catch (OperationCanceledException) { } } _connection.Close(); // workaround for npgsql issue?? await _connection.OpenAsync(); var transaction = _connection.BeginTransaction(); var nextAction = await _connection.QuerySingleOrDefaultAsync <EventQueueItem>("SELECT * FROM \"EventQueue\" WHERE \"NextAttempt\" < @time order by \"NextAttempt\" limit 1 for update skip locked", new { time = DateTime.Now.AddMinutes(1) }); _logger.LogDebug($"Next action: {nextAction?.Action ?? "nothing"}"); if (nextAction == null) { transaction.Rollback(); transaction.Dispose(); continue; } await BaseTask.Go(_connection, nextAction, _serviceProvider, transaction); } }