public Task <IEnumerable <BackgroundTask> > LockNextAvailableAsync(int readAhead) { var all = _tasks.SelectMany(t => t.Value); // None locked, failed or succeeded, must be due, ordered by due time then priority var now = GetTaskTimestamp(); var query = all .Where(t => !t.FailedAt.HasValue && !t.SucceededAt.HasValue && !t.LockedAt.HasValue) .Where(t => t.RunAt <= now) .OrderBy(t => t.RunAt) .ThenBy(t => t.Priority) .AsList(); var tasks = (query.Count > readAhead ? query.Take(readAhead) : query).AsList(); // Lock tasks: if (tasks.Any()) { foreach (var scheduledTask in tasks) { scheduledTask.LockedAt = now; scheduledTask.LockedBy = LockedIdentity.Get(); } } return(Task.FromResult(tasks.AsEnumerable())); }
private async Task LockTasksAsync(IReadOnlyCollection <BackgroundTask> tasks, IDbConnection db, IDbTransaction t) { var sql = $@" UPDATE {TaskTable} SET LockedAt = :Now, LockedBy = :User WHERE Id IN :Ids "; var now = GetTaskTimestamp(); var user = LockedIdentity.Get(); await db.ExecuteAsync(sql, new { Now = now, Ids = tasks.Select(task => task.Id), User = user }, t); foreach (var task in tasks) { task.LockedAt = now; task.LockedBy = user; } }
public async Task <IEnumerable <BackgroundTask> > LockNextAvailableAsync(int readAhead) { var now = GetTaskTimestamp(); var tasks = (await _repository.RetrieveAsync(x => x.LockedAt == null && x.FailedAt == null && x.SucceededAt == null && x.RunAt <= now)).ToList(); foreach (var task in tasks) { task.LockedAt = now; task.LockedBy = LockedIdentity.Get(); await _repository.UpdateAsync(task.Id, task); } return(tasks .OrderBy(x => x.RunAt) .ThenBy(x => x.Priority) .Select(x => (BackgroundTask)x)); }
private void LockTasks(IEnumerable <BackgroundTask> tasks, IDbConnection db, IDbTransaction t) { var now = GetTaskTimestamp(); var user = LockedIdentity.Get(); var matches = tasks.AsList(); var ids = GetTaskIds(matches).AsList(); if (_options.CurrentValue.Store.FilterCorrelatedTasks) { FilterCorrelatedTasks(db, t, now, ids, matches); } var lockTasks = $@" UPDATE {TaskTable} SET LockedAt = @Now, LockedBy = @User WHERE Id IN @Ids; "; _logger.Debug(() => "Locking {TaskCount} tasks", matches.Count); var updated = db.Execute(lockTasks, new { Now = now, Ids = ids, User = user }, t); if (updated != matches.Count) { _logger.Warn(() => "Did not lock the expected number of tasks"); } foreach (var task in matches) { task.LockedAt = now; task.LockedBy = user; } }