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); } }
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), });
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)); } }
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); } }
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); } }
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); } }
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)); }
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); } }
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; } }
public override async Task <int> PurgeInstanceHistoryAsync( OrchestrationDbContext dbContext, string instanceId) { return(await dbContext.Database.ExecuteSqlInterpolatedAsync($"DELETE FROM Executions WHERE InstanceId = {instanceId}")); }
public override async Task Migrate(OrchestrationDbContext dbContext) { await dbContext.Database.MigrateAsync(); }
public override Task Migrate(OrchestrationDbContext dbContext) { return(Task.CompletedTask); }