public async Task <WeeklyReleaseSchedule> ExecuteAsync(QueueId queueId) { queueId.AssertNotNull("queueId"); var parameters = new { QueueId = queueId.Value }; using (var connection = this.connectionFactory.CreateConnection()) { var releaseTimes = await connection.QueryAsync <WeeklyReleaseTime>(Sql, parameters); var hoursOfWeek = releaseTimes.Select(_ => HourOfWeek.Parse(_.HourOfWeek)).ToArray(); if (hoursOfWeek.Length == 0) { throw new Exception( string.Format( "Queue does not have any weekly release times defined. At least one should exist per collection at all times. {0}", queueId)); } return(WeeklyReleaseSchedule.Parse(hoursOfWeek)); } }
public async Task ExecuteAsync(QueueId queueId, WeeklyReleaseSchedule weeklyReleaseSchedule) { queueId.AssertNotNull("queueId"); weeklyReleaseSchedule.AssertNotNull("weeklyReleaseSchedule"); var newWeeklyReleaseTimes = weeklyReleaseSchedule.Value.Select( _ => new WeeklyReleaseTime(queueId.Value, null, (byte)_.Value)); var deletionParameters = new { QueueId = queueId.Value }; // Transaction required on the following, as database must always contain at least one weekly release time per // collection. The absence of weekly release times would cause a breaking inconsistency. using (var transaction = TransactionScopeBuilder.CreateAsync()) { using (var connection = this.connectionFactory.CreateConnection()) { await connection.ExecuteAsync(DeleteWeeklyReleaseTimesSql, deletionParameters); await connection.InsertAsync(newWeeklyReleaseTimes); } transaction.Complete(); } }
public async Task ExecuteAsync(PostId postId, QueueId queueId) { postId.AssertNotNull("postId"); queueId.AssertNotNull("queueId"); var nextLiveDate = await this.getLiveDateOfNewQueuedPost.ExecuteAsync(queueId); var post = new Post(postId.Value) { QueueId = queueId.Value, LiveDate = nextLiveDate }; var parameters = new SqlGenerationParameters <Post, Post.Fields>(post) { UpdateMask = Post.Fields.QueueId | Post.Fields.LiveDate, Conditions = new[] { WherePostLiveDateUniqueToQueue, // Perform locks in 'descending supersets' to avoid deadlock. WherePostNotInQueue } }; using (var connection = this.connectionFactory.CreateConnection()) { var failedConditionIndex = await connection.UpdateAsync(parameters); var concurrencyFailure = failedConditionIndex == 0; if (concurrencyFailure) { throw new OptimisticConcurrencyException(string.Format("Failed to optimistically queue post with queue {0}", queueId)); } } }
public async Task <DateTime> ExecuteAsync(QueueId queueId) { queueId.AssertNotNull("queueId"); var exclusiveLowerBound = await this.getNewQueuedPostLiveDateLowerBound.ExecuteAsync(queueId, DateTime.UtcNow); var weeklyReleaseSchedule = await this.getWeeklyReleaseSchedule.ExecuteAsync(queueId); return(this.queuedPostLiveDateCalculator.GetNextLiveDate( exclusiveLowerBound, weeklyReleaseSchedule)); }
public async Task ExecuteAsync(QueueId queueId) { queueId.AssertNotNull("queueId"); using (var connection = this.connectionFactory.CreateConnection()) { await connection.ExecuteAsync( DeleteSql, new { QueueId = queueId.Value }); } }
public async Task ExecuteAsync(QueueId queueId, WeeklyReleaseSchedule weeklyReleaseSchedule, DateTime now) { queueId.AssertNotNull("queueId"); weeklyReleaseSchedule.AssertNotNull("weeklyReleaseSchedule"); now.AssertUtc("now"); // Transaction required on the following, as we don't want user to see a queue that does not match the collection's release times. using (var transaction = TransactionScopeBuilder.CreateAsync()) { await this.replaceWeeklyReleaseTimes.ExecuteAsync(queueId, weeklyReleaseSchedule); await this.defragmentQueue.ExecuteAsync(queueId, weeklyReleaseSchedule, now); transaction.Complete(); } }
public async Task <int> ExecuteAsync(QueueId queueId, DateTime now) { queueId.AssertNotNull("queueId"); now.AssertUtc("now"); var parameters = new { QueueId = queueId.Value, Now = now }; using (var connection = this.connectionFactory.CreateConnection()) { return(await connection.ExecuteScalarAsync <int>(Sql, parameters)); } }
public async Task ExecuteAsync(QueueId queueId, WeeklyReleaseSchedule weeklyReleaseSchedule, DateTime now) { queueId.AssertNotNull("queueId"); weeklyReleaseSchedule.AssertNotNull("weeklyReleaseSchedule"); now.AssertUtc("now"); var queueSize = await this.getQueueSize.ExecuteAsync(queueId, now); if (queueSize == 0) { return; } var unfragmentedLiveDates = this.liveDateCalculator.GetNextLiveDates(now, weeklyReleaseSchedule, queueSize); await this.updateAllLiveDatesInQueue.ExecuteAsync(queueId, unfragmentedLiveDates, now); }
public async Task ExecuteAsync(QueueId queueId, IReadOnlyList <DateTime> ascendingLiveDates, DateTime now) { queueId.AssertNotNull("queueId"); ascendingLiveDates.AssertNotNull("ascendingLiveDates"); ascendingLiveDates.AssertNonEmpty("ascendingLiveDates"); now.AssertUtc("now"); if (ascendingLiveDates.Any(_ => _.Kind != DateTimeKind.Utc)) { throw new ArgumentException("All dates must be UTC", "ascendingLiveDates"); } if (ascendingLiveDates.First() <= now) { throw new ArgumentException("All dates must be in future", "ascendingLiveDates"); } ascendingLiveDates.Aggregate((previous, current) => { if (previous >= current) { throw new ArgumentException("Must be in ascending order with no duplicates", "ascendingLiveDates"); } return(current); }); var parameters = new DynamicParameters(new { QueueId = queueId.Value, Now = now }); var sql = new StringBuilder(); sql.AppendLine(SqlPreInserts); for (var i = 0; i < ascendingLiveDates.Count; i++) { var rowNumber = i + 1; // Need to match the output of ROW_NUMBER, which is 1-based. sql.Append("INSERT INTO #NewLiveDates VALUES (@LiveDate"); sql.Append(rowNumber); sql.Append(", "); sql.Append(rowNumber); sql.AppendLine(");"); var liveDate = ascendingLiveDates[i]; parameters.Add("LiveDate" + rowNumber, liveDate); } sql.AppendLine(SqlPostInserts); using (var connection = this.connectionFactory.CreateConnection()) { var queueOverflow = await connection.ExecuteScalarAsync <int>(sql.ToString(), parameters); if (queueOverflow != -1) { throw new ArgumentException( string.Format( "Insufficient quantity of live dates provided. Given {0}. Required at least {1}.", ascendingLiveDates.Count, queueOverflow), "ascendingLiveDates"); } } }