internal MySqlDistributedLock Acquire() { Logger.TraceFormat("Acquire resource={0}, timeout={1}", _resource, _timeout); int insertedObjectCount; do { _cancellationToken.ThrowIfCancellationRequested(); var timeLeft = _start.Add(_timeout).Subtract(DateTime.UtcNow); using (ResourceLock.AcquireOne( _connection, _storageOptions.TablesPrefix, timeLeft, _cancellationToken, LockableResource.Lock)) { insertedObjectCount = AcquireLock(); } if (ContinueCondition(insertedObjectCount)) { _cancellationToken.WaitHandle.WaitOne(DelayBetweenPasses); _cancellationToken.ThrowIfCancellationRequested(); } } while (ContinueCondition(insertedObjectCount)); if (insertedObjectCount == 0) { throw new MySqlDistributedLockException("cannot acquire lock"); } return this; }
private int AggregateCounter(MySqlConnection connection) { using (ResourceLock.AcquireOne( connection, _options.TablesPrefix, LockableResource.Counter)) { return(connection.Execute( GetAggregationQuery(), new { now = DateTime.UtcNow, count = NumberOfRecordsInSinglePass })); } }
public IFetchedJob Dequeue(string[] queues, CancellationToken cancellationToken) { if (queues is null || !queues.Any()) { throw new ArgumentException("Queue array must be non-empty.", nameof(queues)); } var token = Guid.NewGuid().ToString(); // I'm not sure if this is used correctly... var expiration = _options.InvisibilityTimeout; // the connection variable is mutable, it job is claimed then this connection // is passed to job itself, and variable is set to null so it does not get // disposed here in such case var connection = _storage.CreateAndOpenConnection(); try { while (true) { cancellationToken.ThrowIfCancellationRequested(); using (ResourceLock.AcquireOne( connection, _options.TablesPrefix, LockableResource.Queue)) { var updated = ClaimJob(connection, queues, expiration, token); if (updated != 0) { var fetchedJob = FetchJobByToken(connection, token); return(new MySqlFetchedJob( _storage, _options, Interlocked.Exchange(ref connection, null), fetchedJob)); } } cancellationToken.WaitHandle.WaitOne(_options.QueuePollInterval); cancellationToken.ThrowIfCancellationRequested(); } } catch (MySqlException ex) { Logger.ErrorException(ex.Message, ex); throw; } finally { if (connection != null) { _storage.ReleaseConnection(connection); } } }
public void Requeue() { Logger.TraceFormat("Requeue JobId={0}", JobId); using (ResourceLock.AcquireOne( _connection, _options.TablesPrefix, LockableResource.Queue)) { _connection.Execute( $"update `{_options.TablesPrefix}JobQueue` set FetchedAt = null where Id = @id", new { id = _id }); } _requeued = true; }
public void RemoveFromQueue() { Logger.TraceFormat("RemoveFromQueue JobId={0}", JobId); using (ResourceLock.AcquireOne( _connection, _options.TablesPrefix, LockableResource.Queue)) { _connection.Execute( $"delete from `{_options.TablesPrefix}JobQueue` where Id = @id", new { id = _id }); } _removed = true; }
internal void Release() { Logger.TraceFormat("Release resource={0}", _resource); using (ResourceLock.AcquireOne( _connection, _storageOptions.TablesPrefix, _timeout, CancellationToken.None, LockableResource.Lock)) { _connection.Execute( $"DELETE FROM `{_storageOptions.TablesPrefix}DistributedLock` " + "WHERE Resource = @resource", new { resource = _resource }); } }
private void Enqueue( IDbConnection connection, IDbTransaction transaction, string queue, string jobId) { Logger.TraceFormat("Enqueue JobId={0} Queue={1}", jobId, queue); using (ResourceLock.AcquireOne( connection, transaction, _options.TablesPrefix, LockableResource.Queue)) { connection.Execute( $@"/* MySqlJobQueue.Enqueue */ insert into `{_options.TablesPrefix}JobQueue` (JobId, Queue) values (@jobId, @queue)", new { jobId, queue }, transaction); } }
public static void Upgrade(MySqlConnection connection, string tablesPrefix = null) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } var prefix = tablesPrefix ?? string.Empty; using (ResourceLock.AcquireOne( connection, prefix, MigrationTimeout, CancellationToken.None, LockableResource.Migration)) { var resourceName = $"{typeof(MySqlObjectsInstaller).Namespace}.Migrations.xml"; var document = XElement.Parse(GetStringResource(resourceName)); EnsureMigrationsTable(connection, prefix); var migrations = document .Elements("migration") .Select(e => new { id = e.Attribute("id")?.Value, script = e.Value }) .ToArray(); foreach (var migration in migrations) { var alreadyApplied = IsMigrationApplied(connection, prefix, migration.id); if (alreadyApplied) { continue; } ApplyMigration(connection, migration.script, prefix, migration.id); } } }