Example #1
0
        public override async Task <ActivityMessage> TryLockNextActivityMessageAsync(
            OrchestrationDbContext dbContext,
            TimeSpan lockTimeout)
        {
            using (var transaction = dbContext.Database.BeginTransaction(TransactionIsolationLevel))
            {
                var instance = await dbContext.ActivityMessages.FromSqlRaw(@"
                    SELECT TOP 1 * FROM ActivityMessages WITH (UPDLOCK, READPAST)
                    WHERE LockedUntil <= {0}
                    ORDER BY LockedUntil
                ", DateTime.UtcNow).FirstOrDefaultAsync();

                if (instance == null)
                {
                    return(null);
                }

                instance.LockId      = Guid.NewGuid().ToString();
                instance.LockedUntil = DateTime.UtcNow.Add(lockTimeout);
                await dbContext.SaveChangesAsync();

                await transaction.CommitAsync();

                return(instance);
            }
        }
Example #2
0
        public async Task <OrchestrationMessage> CreateOrchestrationMessageAsync(
            TaskMessage message,
            int sequence,
            OrchestrationDbContext context,
            IDictionary <string, string> knownQueues = null)
        {
            if (knownQueues == null || !knownQueues.TryGetValue(message.OrchestrationInstance.InstanceId, out var queue))
            {
                var instance = await context.Instances.FindAsync(message.OrchestrationInstance.InstanceId);

                if (instance == null)
                {
                    throw new Exception($"Instance {message.OrchestrationInstance.InstanceId} not found");
                }

                queue = instance.LastQueueName;
            }

            return(new OrchestrationMessage
            {
                Id = Guid.NewGuid(),
                InstanceId = message.OrchestrationInstance.InstanceId,
                ExecutionId = message.OrchestrationInstance.ExecutionId,
                Queue = queue,
                SequenceNumber = sequence,
                AvailableAt = message.Event is TimerFiredEvent timerFiredEvent
                    ? timerFiredEvent.FireAt.ToUniversalTime()
                    : DateTime.UtcNow,
                Message = _options.DataConverter.Serialize(message),
            });
Example #3
0
        public override Task <ActivityMessage> TryLockNextActivityMessageAsync(
            OrchestrationDbContext dbContext,
            TimeSpan lockTimeout)
        {
            lock (_lock)
            {
                var activityMessage = (
                    from message in dbContext.ActivityMessages
                    where message.LockedUntil <= DateTime.UtcNow &&
                    message.Instance.LockedUntil <= DateTime.UtcNow
                    orderby message.LockedUntil
                    select message
                    ).FirstOrDefault();

                if (activityMessage == null)
                {
                    return(Task.FromResult(default(ActivityMessage)));
                }

                activityMessage.LockId      = Guid.NewGuid().ToString();
                activityMessage.LockedUntil = DateTime.UtcNow.Add(lockTimeout);
                dbContext.SaveChanges();

                return(Task.FromResult(activityMessage));
            }
        }
Example #4
0
        public override async Task <Instance> TryLockNextInstanceAsync(
            OrchestrationDbContext dbContext,
            TimeSpan lockTimeout)
        {
            using (var transaction = dbContext.Database.BeginTransaction(TransactionIsolationLevel))
            {
                var instance = await dbContext.Instances.FromSqlRaw(@"
                    SELECT TOP 1 Instances.* FROM OrchestrationMessages WITH (UPDLOCK, READPAST)
                        INNER JOIN Instances WITH (UPDLOCK, READPAST, FORCESEEK)
                            ON OrchestrationMessages.InstanceId = Instances.InstanceId
                    WHERE
                        OrchestrationMessages.AvailableAt <= {0}
                        AND Instances.LockedUntil <= {0}
                    ORDER BY OrchestrationMessages.AvailableAt
                ", DateTime.UtcNow).FirstOrDefaultAsync();

                if (instance == null)
                {
                    return(null);
                }

                instance.LockId      = Guid.NewGuid().ToString();
                instance.LockedUntil = DateTime.UtcNow.Add(lockTimeout);
                await dbContext.SaveChangesAsync();

                await transaction.CommitAsync();

                return(instance);
            }
        }
Example #5
0
        public override async Task <ActivityMessage> TryLockNextActivityMessageAsync(
            OrchestrationDbContext dbContext,
            string[] queues,
            TimeSpan lockTimeout)
        {
            using (var transaction = dbContext.Database.BeginTransaction(TransactionIsolationLevel))
            {
                var queuesParams = string.Join(",", queues.Select((_, i) => $"{{{i}}}"));
                var utcNowParam  = $"{{{queues.Length}}}";
                var parameters   = queues.Cast <object>().Concat(new object[] { DateTime.UtcNow }).ToArray();

                var instance = await dbContext.ActivityMessages.FromSqlRaw($@"
                    SELECT TOP 1 * FROM ActivityMessages
                    WITH (UPDLOCK, READPAST)
                    WHERE Queue IN ({queuesParams})
                        AND LockedUntil <= {utcNowParam}
                    ORDER BY LockedUntil
                ", parameters).FirstOrDefaultAsync();

                if (instance == null)
                {
                    return(null);
                }

                instance.LockId      = Guid.NewGuid().ToString();
                instance.LockedUntil = DateTime.UtcNow.Add(lockTimeout);
                await dbContext.SaveChangesAsync();

                await transaction.CommitAsync();

                return(instance);
            }
        }
        public override async Task <Instance> TryLockNextInstanceAsync(
            OrchestrationDbContext dbContext,
            TimeSpan lockTimeout)
        {
            using (var transaction = dbContext.Database.BeginTransaction(TransactionIsolationLevel))
            {
                var instance = await dbContext.Instances.FromSqlRaw(@"
                    SELECT ""Instances"".* FROM ""OrchestrationMessages""
                        INNER JOIN ""Instances""
                            ON ""OrchestrationMessages"".""InstanceId"" = ""Instances"".""InstanceId""
                    WHERE
                        ""OrchestrationMessages"".""AvailableAt"" <= {0}
                        AND ""Instances"".""LockedUntil"" <= {0}
                    ORDER BY ""OrchestrationMessages"".""AvailableAt""
                    LIMIT 1
                    FOR UPDATE SKIP LOCKED
                ", DateTime.UtcNow).FirstOrDefaultAsync();

                if (instance == null)
                {
                    return(null);
                }

                instance.LockId      = Guid.NewGuid().ToString();
                instance.LockedUntil = DateTime.UtcNow.Add(lockTimeout);
                await dbContext.SaveChangesAsync();

                await transaction.CommitAsync();

                return(instance);
            }
        }
Example #7
0
        public override Task <Instance> TryLockNextInstanceAsync(
            OrchestrationDbContext dbContext,
            string[] queues,
            TimeSpan lockTimeout)
        {
            lock (_lock)
            {
                var instance = (
                    from message in dbContext.OrchestrationMessages
                    where message.AvailableAt <= DateTime.UtcNow &&
                    queues.Contains(message.Queue) &&
                    message.Instance.LockedUntil <= DateTime.UtcNow
                    orderby message.AvailableAt
                    select message.Instance
                    ).FirstOrDefault();

                if (instance == null)
                {
                    return(Task.FromResult(default(Instance)));
                }

                instance.LockId      = Guid.NewGuid().ToString();
                instance.LockedUntil = DateTime.UtcNow.Add(lockTimeout);
                dbContext.SaveChanges();

                return(Task.FromResult(instance));
            }
        }
        public override async Task <Instance> TryLockNextInstanceAsync(
            OrchestrationDbContext dbContext,
            TimeSpan lockTimeout)
        {
            using (var transaction = dbContext.Database.BeginTransaction(TransactionIsolationLevel))
            {
                var instance = await dbContext.Instances.FromSqlRaw(@"
                    SELECT Instances.* FROM OrchestrationMessages
	                    STRAIGHT_JOIN Instances FORCE INDEX FOR JOIN (PRIMARY)
                            ON OrchestrationMessages.InstanceId = Instances.InstanceId
                    WHERE
                        OrchestrationMessages.AvailableAt <= {0}
                        AND Instances.LockedUntil <= {0}
                    ORDER BY OrchestrationMessages.AvailableAt
                    LIMIT 1
                    FOR UPDATE SKIP LOCKED
                ", DateTime.UtcNow).FirstOrDefaultAsync();

                if (instance == null)
                {
                    return(null);
                }

                instance.LockId      = Guid.NewGuid().ToString();
                instance.LockedUntil = DateTime.UtcNow.Add(lockTimeout);
                await dbContext.SaveChangesAsync();

                await transaction.CommitAsync();

                return(instance);
            }
        }
Example #9
0
        public override Task <int> PurgeInstanceHistoryAsync(
            OrchestrationDbContext dbContext,
            string instanceId)
        {
            var executions = dbContext.Executions.Where(e => e.InstanceId == instanceId).ToArray();

            dbContext.Executions.RemoveRange(executions);
            dbContext.SaveChanges();
            return(Task.FromResult(executions.Length));
        }
Example #10
0
        public override Task PurgeOrchestrationHistoryAsync(
            OrchestrationDbContext dbContext,
            DateTime thresholdDateTimeUtc,
            OrchestrationStateTimeRangeFilterType timeRangeFilterType)
        {
            var executions = timeRangeFilterType switch
            {
                OrchestrationStateTimeRangeFilterType.OrchestrationCreatedTimeFilter =>
                dbContext.Executions.Where(e => e.CreatedTime < thresholdDateTimeUtc).ToArray(),
                OrchestrationStateTimeRangeFilterType.OrchestrationLastUpdatedTimeFilter =>
                dbContext.Executions.Where(e => e.LastUpdatedTime < thresholdDateTimeUtc).ToArray(),
                OrchestrationStateTimeRangeFilterType.OrchestrationCompletedTimeFilter =>
                dbContext.Executions.Where(e => e.CompletedTime < thresholdDateTimeUtc).ToArray(),
                _ => throw new NotImplementedException()
            };

            dbContext.Executions.RemoveRange(executions);
            dbContext.SaveChanges();
            return(Task.CompletedTask);
        }
        public override async Task <Instance> TryLockNextInstanceAsync(
            OrchestrationDbContext dbContext,
            string[] queues,
            TimeSpan lockTimeout)
        {
            using (var transaction = dbContext.Database.BeginTransaction(TransactionIsolationLevel))
            {
                var queuesParams = string.Join(",", queues.Select((_, i) => $"{{{i}}}"));
                var utcNowParam  = $"{{{queues.Length}}}";
                var parameters   = queues.Cast <object>().Concat(new object[] { DateTime.UtcNow }).ToArray();

                var instance = await dbContext.Instances.FromSqlRaw($@"
                    SELECT ""Instances"".* FROM ""OrchestrationMessages""
                        INNER JOIN ""Instances""
                            ON ""OrchestrationMessages"".""InstanceId"" = ""Instances"".""InstanceId""
                    WHERE
                        ""OrchestrationMessages"".""AvailableAt"" <= {utcNowParam}
                        AND ""OrchestrationMessages"".""Queue"" IN ({queuesParams})
                        AND ""Instances"".""LockedUntil"" <= {utcNowParam}
                    ORDER BY ""OrchestrationMessages"".""AvailableAt""
                    LIMIT 1
                    FOR UPDATE SKIP LOCKED
                ", parameters).FirstOrDefaultAsync();

                if (instance == null)
                {
                    return(null);
                }

                instance.LockId      = Guid.NewGuid().ToString();
                instance.LockedUntil = DateTime.UtcNow.Add(lockTimeout);
                await dbContext.SaveChangesAsync();

                await transaction.CommitAsync();

                return(instance);
            }
        }
Example #12
0
        public override async Task PurgeOrchestrationHistoryAsync(
            OrchestrationDbContext dbContext,
            DateTime thresholdDateTimeUtc,
            OrchestrationStateTimeRangeFilterType timeRangeFilterType)
        {
            switch (timeRangeFilterType)
            {
            case OrchestrationStateTimeRangeFilterType.OrchestrationCreatedTimeFilter:
                await dbContext.Database.ExecuteSqlInterpolatedAsync($"DELETE FROM Executions WHERE CreatedTime < {thresholdDateTimeUtc}");

                break;

            case OrchestrationStateTimeRangeFilterType.OrchestrationLastUpdatedTimeFilter:
                await dbContext.Database.ExecuteSqlInterpolatedAsync($"DELETE FROM Executions WHERE LastUpdatedTime < {thresholdDateTimeUtc}");

                break;

            case OrchestrationStateTimeRangeFilterType.OrchestrationCompletedTimeFilter:
                await dbContext.Database.ExecuteSqlInterpolatedAsync($"DELETE FROM Executions WHERE CompletedTime < {thresholdDateTimeUtc}");

                break;
            }
        }
Example #13
0
 public override async Task <int> PurgeInstanceHistoryAsync(
     OrchestrationDbContext dbContext,
     string instanceId)
 {
     return(await dbContext.Database.ExecuteSqlInterpolatedAsync($"DELETE FROM Executions WHERE InstanceId = {instanceId}"));
 }
Example #14
0
 public override async Task Migrate(OrchestrationDbContext dbContext)
 {
     await dbContext.Database.MigrateAsync();
 }
Example #15
0
 public override Task Migrate(OrchestrationDbContext dbContext)
 {
     return(Task.CompletedTask);
 }