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()));
        }
Example #2
0
        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;
            }
        }