public void RemoveFromQueue() { lock (_syncRoot) { _storage.UseConnection(null, connection => { connection.Execute( $"delete from {_storage.SchemaName}.JobQueue where Id = @id", new { id = Id }, commandTimeout: _storage.CommandTimeout); }); _removedFromQueue = true; } }
private void UseConnectionDistributedLock(SqlServerStorage storage, Action <DbConnection> action) { try { storage.UseConnection(null, connection => { SqlServerDistributedLock.Acquire(connection, DistributedLockKey, DefaultLockTimeout); try { action(connection); } finally { SqlServerDistributedLock.Release(connection, DistributedLockKey); } }); } catch (DistributedLockTimeoutException e) when(e.Resource == DistributedLockKey) { // DistributedLockTimeoutException here doesn't mean that outdated records weren't removed. // It just means another Hangfire server did this work. _logger.Log( LogLevel.Debug, () => $@"An exception was thrown during acquiring distributed lock on the {DistributedLockKey} resource within {DefaultLockTimeout.TotalSeconds} seconds. Outdated records were not removed. It will be retried in {_checkInterval.TotalSeconds} seconds.", e); } }
public void Execute(CancellationToken cancellationToken) { Logger.Debug("Aggregating records in 'Counter' table..."); int removedCount = 0; do { _storage.UseConnection(null, connection => { removedCount = connection.Execute( GetAggregationQuery(_storage), new { now = DateTime.UtcNow, count = NumberOfRecordsInSinglePass }, commandTimeout: 0); }); if (removedCount >= NumberOfRecordsInSinglePass) { cancellationToken.Wait(DelayBetweenPasses); cancellationToken.ThrowIfCancellationRequested(); } // ReSharper disable once LoopVariableIsNeverChangedInsideLoop } while (removedCount >= NumberOfRecordsInSinglePass); Logger.Trace("Records from the 'Counter' table aggregated."); cancellationToken.Wait(_interval); }
public void Execute(CancellationToken cancellationToken) { foreach (var table in ProcessedTables) { Logger.Debug($"Removing outdated records from the '{table}' table..."); _storage.UseConnection(connection => { SqlServerDistributedLock.Acquire(connection, DistributedLockKey, DefaultLockTimeout); try { ExecuteNonQuery( connection, GetQuery(_storage.SchemaName, table), cancellationToken, new SqlParameter("@count", NumberOfRecordsInSinglePass), new SqlParameter("@now", DateTime.UtcNow)); } finally { SqlServerDistributedLock.Release(connection, DistributedLockKey); } }); Logger.Trace($"Outdated records removed from the '{table}' table."); } cancellationToken.WaitHandle.WaitOne(_checkInterval); }
public void RemoveFromQueue() { lock (_syncRoot) { if (!FetchedAt.HasValue) { return; } _storage.UseConnection(null, connection => { connection.Execute( $"delete JQ from [{_storage.SchemaName}].JobQueue JQ with ({GetTableHints()}) where Queue = @queue and Id = @id and FetchedAt = @fetchedAt", new { queue = Queue, id = Id, fetchedAt = FetchedAt }, commandTimeout: _storage.CommandTimeout); }); _removedFromQueue = true; } }
public void Execute(CancellationToken cancellationToken) { foreach (var table in ProcessedTables) { Logger.DebugFormat("Removing outdated records from table '{0}'...", table); int removedCount = 0; do { _storage.UseConnection(connection => { SqlServerDistributedLock.Acquire(connection, DistributedLockKey, DefaultLockTimeout); try { removedCount = connection.Execute( String.Format(@" set transaction isolation level read committed; delete top (@count) from [{0}].[{1}] with (readpast) where ExpireAt < @now;", _storage.GetSchemaName(), table), new { now = DateTime.UtcNow, count = NumberOfRecordsInSinglePass }); } finally { SqlServerDistributedLock.Release(connection, DistributedLockKey); } }); if (removedCount > 0) { Logger.Trace(String.Format("Removed {0} outdated record(s) from '{1}' table.", removedCount, table)); cancellationToken.WaitHandle.WaitOne(DelayBetweenPasses); cancellationToken.ThrowIfCancellationRequested(); } } while (removedCount != 0); } cancellationToken.WaitHandle.WaitOne(_checkInterval); }
public void Execute(CancellationToken cancellationToken) { foreach (var table in ProcessedTables) { Logger.Debug($"Removing outdated records from table '{table}'..."); int removedCount = 0; do { _storage.UseConnection(connection => { SqlServerDistributedLock.Acquire(connection, DistributedLockKey, DefaultLockTimeout); try { removedCount = connection.Execute( $@"set transaction isolation level read committed; delete top (@count) from [{_storage.SchemaName}].[{table}] with (readpast) where ExpireAt < @now;", new { now = DateTime.UtcNow, count = NumberOfRecordsInSinglePass }); } finally { SqlServerDistributedLock.Release(connection, DistributedLockKey); } }); if (removedCount > 0) { Logger.Trace($"Removed {removedCount} outdated record(s) from '{table}' table."); cancellationToken.WaitHandle.WaitOne(DelayBetweenPasses); cancellationToken.ThrowIfCancellationRequested(); } // ReSharper disable once LoopVariableIsNeverChangedInsideLoop } while (removedCount != 0); } cancellationToken.WaitHandle.WaitOne(_checkInterval); }
public void Execute(CancellationToken cancellationToken) { Logger.DebugFormat("Aggregating records in 'Counter' table..."); int removedCount = 0; do { _storage.UseConnection(connection => { removedCount = connection.Execute( GetAggregationQuery(_storage), new { now = DateTime.UtcNow, count = NumberOfRecordsInSinglePass }); }); if (removedCount >= NumberOfRecordsInSinglePass) { cancellationToken.WaitHandle.WaitOne(DelayBetweenPasses); cancellationToken.ThrowIfCancellationRequested(); } } while (removedCount >= NumberOfRecordsInSinglePass); cancellationToken.WaitHandle.WaitOne(_interval); }
public override string CreateExpiredJob( Job job, IDictionary <string, string> parameters, DateTime createdAt, TimeSpan expireIn) { if (job == null) { throw new ArgumentNullException(nameof(job)); } if (parameters == null) { throw new ArgumentNullException(nameof(parameters)); } string createJobSql = $@"insert into [{_storage.SchemaName}].Job (InvocationData, Arguments, CreatedAt, ExpireAt) output inserted.Id values (@invocationData, @arguments, @createdAt, @expireAt)"; var invocationData = InvocationData.Serialize(job); return(_storage.UseConnection(_dedicatedConnection, connection => { var jobId = connection.ExecuteScalar <long>( createJobSql, new { invocationData = JobHelper.ToJson(invocationData), arguments = invocationData.Arguments, createdAt = createdAt, expireAt = createdAt.Add(expireIn) }, commandTimeout: _storage.CommandTimeout).ToString(); if (parameters.Count > 0) { string insertParameterSql = $@"insert into [{_storage.SchemaName}].JobParameter (JobId, Name, Value) values (@jobId, @name, @value)"; var commandBatch = new SqlCommandBatch(preferBatching: _storage.CommandBatchMaxTimeout.HasValue); foreach (var parameter in parameters) { commandBatch.Append(insertParameterSql, new SqlParameter("@jobId", long.Parse(jobId)), new SqlParameter("@name", parameter.Key), new SqlParameter("@value", (object)parameter.Value ?? DBNull.Value)); } commandBatch.Connection = connection; commandBatch.CommandTimeout = _storage.CommandTimeout; commandBatch.CommandBatchMaxTimeout = _storage.CommandBatchMaxTimeout; commandBatch.ExecuteNonQuery(); } return jobId; })); }
public override string CreateExpiredJob( Job job, IDictionary <string, string> parameters, DateTime createdAt, TimeSpan expireIn) { if (job == null) { throw new ArgumentNullException(nameof(job)); } if (parameters == null) { throw new ArgumentNullException(nameof(parameters)); } string createJobSql = $@"insert into [{_storage.SchemaName}].Job (Id, InvocationData, Arguments, CreatedAt, ExpireAt) output inserted.Id values (@id, @invocationData, @arguments, @createdAt, @expireAt)"; var invocationData = InvocationData.Serialize(job); return(_storage.UseConnection(connection => { var jobId = Guid.NewGuid(); connection.Execute( createJobSql, new { id = jobId, invocationData = JobHelper.ToJson(invocationData), arguments = invocationData.Arguments, createdAt = createdAt, expireAt = createdAt.Add(expireIn) }, commandTimeout: _storage.CommandTimeout).ToString(); if (parameters.Count > 0) { var parameterArray = new object[parameters.Count]; int parameterIndex = 0; foreach (var parameter in parameters) { parameterArray[parameterIndex++] = new { id = Guid.NewGuid(), jobId = jobId, name = parameter.Key, value = parameter.Value }; } string insertParameterSql = $@"insert into [{_storage.SchemaName}].JobParameter (Id, JobId, Name, Value) values (@id, @jobId, @name, @value)"; connection.Execute(insertParameterSql, parameterArray, commandTimeout: _storage.CommandTimeout); } return jobId.ToString(); })); }
private T UseConnection <T>(Func <DbConnection, T> action) { return(_storage.UseConnection(action)); }
public override string CreateExpiredJob( Job job, IDictionary <string, string> parameters, DateTime createdAt, TimeSpan expireIn) { if (job == null) { throw new ArgumentNullException(nameof(job)); } if (parameters == null) { throw new ArgumentNullException(nameof(parameters)); } string createJobSql = $@"insert into [{_storage.SchemaName}].Job (InvocationData, Arguments, CreatedAt, ExpireAt) values (@invocationData, @arguments, @createdAt, @expireAt); SELECT CAST(SCOPE_IDENTITY() as int)"; var invocationData = InvocationData.Serialize(job); return(_storage.UseConnection(connection => { var jobId = connection.Query <int>( createJobSql, new { invocationData = JobHelper.ToJson(invocationData), arguments = invocationData.Arguments, createdAt = createdAt, expireAt = createdAt.Add(expireIn) }).Single().ToString(); if (parameters.Count > 0) { var parameterArray = new object[parameters.Count]; int parameterIndex = 0; foreach (var parameter in parameters) { parameterArray[parameterIndex++] = new { jobId = jobId, name = parameter.Key, value = parameter.Value }; } string insertParameterSql = $@"insert into [{_storage.SchemaName}].JobParameter (JobId, Name, Value) values (@jobId, @name, @value)"; connection.Execute(insertParameterSql, parameterArray); } return jobId; })); }