public PostgreSqlDistributedLock(string resource, TimeSpan timeout, IDbConnection connection, PostgreSqlStorageOptions options) { if (string.IsNullOrEmpty(resource)) { throw new ArgumentNullException(nameof(resource)); } if (connection == null) { throw new ArgumentNullException(nameof(connection)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } _resource = resource; _connection = connection; _options = options; if (_options.UseNativeDatabaseTransactions) { PostgreSqlDistributedLock_Init_Transaction(resource, timeout, connection, options); } else { PostgreSqlDistributedLock_Init_UpdateCount(resource, timeout, connection, options); } }
public PostgreSqlConnection( NpgsqlConnection connection, PersistentJobQueueProviderCollection queueProviders, PostgreSqlStorageOptions options) : this(connection, queueProviders, options, true) { }
/// <summary> /// Initializes PostgreSqlStorage from the provided PostgreSqlStorageOptions and either the provided connection /// string or the connection string with provided name pulled from the application config file. /// </summary> /// <param name="nameOrConnectionString">Either a SQL Server connection string or the name of /// a SQL Server connection string located in the connectionStrings node in the application config</param> /// <param name="connectionSetup">Optional setup action to apply to created connections</param> /// <param name="options"></param> /// <exception cref="ArgumentNullException"><paramref name="nameOrConnectionString"/> argument is null.</exception> /// <exception cref="ArgumentNullException"><paramref name="options"/> argument is null.</exception> /// <exception cref="ArgumentException"><paramref name="nameOrConnectionString"/> argument is neither /// a valid SQL Server connection string nor the name of a connection string in the application /// config file.</exception> public PostgreSqlStorage(string nameOrConnectionString, Action <NpgsqlConnection> connectionSetup, PostgreSqlStorageOptions options) { if (nameOrConnectionString == null) { throw new ArgumentNullException(nameof(nameOrConnectionString)); } _options = options ?? throw new ArgumentNullException(nameof(options)); if (IsConnectionString(nameOrConnectionString)) { _connectionString = nameOrConnectionString; } else { throw new ArgumentException( $"Could not find connection string with name '{nameOrConnectionString}' in application config file"); } _connectionSetup = connectionSetup; if (options.PrepareSchemaIfNecessary) { using (var connection = CreateAndOpenConnection()) { PostgreSqlObjectsInstaller.Install(connection, options.SchemaName); } } InitializeQueueProviders(); }
public PostgreSqlFetchedJob( IDbConnection connection, PostgreSqlStorageOptions options, int id, string jobId, string queue) { if (connection == null) { throw new ArgumentNullException("connection"); } if (jobId == null) { throw new ArgumentNullException("jobId"); } if (queue == null) { throw new ArgumentNullException("queue"); } if (options == null) { throw new ArgumentNullException("options"); } _connection = connection; _options = options; Id = id; JobId = jobId; Queue = queue; }
/// <summary> /// Initializes PostgreSqlStorage from the provided PostgreSqlStorageOptions and either the provided connection /// string or the connection string with provided name pulled from the application config file. /// </summary> /// <param name="nameOrConnectionString">Either a SQL Server connection string or the name of /// a SQL Server connection string located in the connectionStrings node in the application config</param> /// <param name="options"></param> /// <exception cref="ArgumentNullException"><paramref name="nameOrConnectionString"/> argument is null.</exception> /// <exception cref="ArgumentNullException"><paramref name="options"/> argument is null.</exception> /// <exception cref="ArgumentException"><paramref name="nameOrConnectionString"/> argument is neither /// a valid SQL Server connection string nor the name of a connection string in the application /// config file.</exception> public PostgreSqlStorage(string nameOrConnectionString, PostgreSqlStorageOptions options) { if (nameOrConnectionString == null) throw new ArgumentNullException(nameof(nameOrConnectionString)); if (options == null) throw new ArgumentNullException(nameof(options)); _options = options; if (IsConnectionString(nameOrConnectionString)) { _connectionString = nameOrConnectionString; } else if (IsConnectionStringInConfiguration(nameOrConnectionString)) { _connectionString = ConfigurationManager.ConnectionStrings[nameOrConnectionString].ConnectionString; } else { throw new ArgumentException( $"Could not find connection string with name '{nameOrConnectionString}' in application config file"); } if (options.PrepareSchemaIfNecessary) { using (var connection = CreateAndOpenConnection()) { PostgreSqlObjectsInstaller.Install(connection, options.SchemaName); } } InitializeQueueProviders(); }
/// <summary> /// Tells the bootstrapper to use PostgreSQL as a job storage /// with the given options, that can be accessed using the specified /// connection string or its name. /// </summary> /// <param name="configuration">Configuration</param> /// <param name="nameOrConnectionString">Connection string or its name</param> /// <param name="options">Advanced options</param> public static IGlobalConfiguration <PostgreSqlStorage> UsePostgreSqlStorage( this IGlobalConfiguration configuration, string nameOrConnectionString, PostgreSqlStorageOptions options) { return(configuration.UsePostgreSqlStorage(nameOrConnectionString, null, options)); }
/// <summary> /// Initializes a new instance of the <see cref="PostgreSqlStorage"/> class with /// explicit instance of the <see cref="NpgsqlConnection"/> class that will be used /// to query the data. /// </summary> /// <param name="existingConnection">Existing connection</param> /// <param name="options">PostgreSqlStorageOptions</param> public PostgreSqlStorage(NpgsqlConnection existingConnection, PostgreSqlStorageOptions options) { if (existingConnection == null) { throw new ArgumentNullException(nameof(existingConnection)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } var connectionStringBuilder = new NpgsqlConnectionStringBuilder(existingConnection.ConnectionString); if (!options.EnableTransactionScopeEnlistment) { if (connectionStringBuilder.Enlist) { throw new ArgumentException( $"TransactionScope enlistment must be enabled by setting {nameof(PostgreSqlStorageOptions)}.{nameof(options.EnableTransactionScopeEnlistment)} to `true`."); } } _existingConnection = existingConnection; _options = options; InitializeQueueProviders(); }
private static void PostgreSqlDistributedLock_Init_Transaction(string resource, TimeSpan timeout, IDbConnection connection, PostgreSqlStorageOptions options) { var lockAcquiringTime = Stopwatch.StartNew(); bool tryAcquireLock = true; while (tryAcquireLock) { TryRemoveDeadlock(resource, connection, options); try { int rowsAffected = -1; using (var trx = connection.BeginTransaction(IsolationLevel.RepeatableRead)) { rowsAffected = connection.Execute($@" INSERT INTO ""{options.SchemaName}"".""lock""(""resource"", ""acquired"") SELECT @resource, @acquired WHERE NOT EXISTS ( SELECT 1 FROM ""{options.SchemaName}"".""lock"" WHERE ""resource"" = @resource ); ", new { resource = resource, acquired = DateTime.UtcNow }, trx); trx.Commit(); } if (rowsAffected > 0) return; } catch { } if (lockAcquiringTime.ElapsedMilliseconds > timeout.TotalMilliseconds) { tryAcquireLock = false; } else { int sleepDuration = (int)(timeout.TotalMilliseconds - lockAcquiringTime.ElapsedMilliseconds); if (sleepDuration > 1000) sleepDuration = 1000; if (sleepDuration > 0) { Thread.Sleep(sleepDuration); } else { tryAcquireLock = false; } } } throw new PostgreSqlDistributedLockException( $"Could not place a lock on the resource \'{resource}\': Lock timeout."); }
public JobQueue(IConnectionProvider connectionProvider, PostgreSqlStorageOptions options) { Guard.ThrowIfNull(connectionProvider, nameof(connectionProvider)); Guard.ThrowIfNull(options, nameof(options)); _connectionProvider = connectionProvider; _options = options; }
public PostgreSqlJobQueue(IDbConnection connection, PostgreSqlStorageOptions options) { if (options == null) throw new ArgumentNullException("options"); if (connection == null) throw new ArgumentNullException("connection"); _options = options; _connection = connection; }
public PostgreSqlJobQueueProvider(PostgreSqlStorageOptions options) { if (options == null) { throw new ArgumentNullException("options"); } _options = options; }
public ExpirationManager(PostgreSqlStorage storage, PostgreSqlStorageOptions options, TimeSpan checkInterval) { if (storage == null) throw new ArgumentNullException("storage"); if (options == null) throw new ArgumentNullException("options"); _options = options; _storage = storage; _checkInterval = checkInterval; }
public PostgreSqlWriteOnlyTransaction( NpgsqlConnection connection, PostgreSqlStorageOptions options, PersistentJobQueueProviderCollection queueProviders) { _connection = connection ?? throw new ArgumentNullException(nameof(connection)); _options = options ?? throw new ArgumentNullException(nameof(options)); _queueProviders = queueProviders ?? throw new ArgumentNullException(nameof(queueProviders)); }
public PostgreSqlMonitoringApi( PostgreSqlStorage storage, PostgreSqlStorageOptions options, PersistentJobQueueProviderCollection queueProviders) { _storage = storage ?? throw new ArgumentNullException(nameof(storage)); _options = options ?? throw new ArgumentNullException(nameof(options)); _queueProviders = queueProviders ?? throw new ArgumentNullException(nameof(queueProviders)); }
/// <summary> /// Tells the bootstrapper to use PostgreSQL as a job storage /// with the given options, that can be accessed using the specified /// connection string or its name. /// </summary> /// <param name="configuration">Configuration</param> /// <param name="nameOrConnectionString">Connection string or its name</param> /// <param name="options">Advanced options</param> public static IGlobalConfiguration <PostgreSqlStorage> UsePostgreSqlStorage( this IGlobalConfiguration configuration, string nameOrConnectionString, PostgreSqlStorageOptions options) { DapperNodaTimeHelpers.AddDapperNodaTime(); return(configuration.UsePostgreSqlStorage(nameOrConnectionString, null, options)); }
public PostgreSqlMonitoringApi( string connectionString, PostgreSqlStorageOptions options, PersistentJobQueueProviderCollection queueProviders) { _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); _options = options ?? throw new ArgumentNullException(nameof(options)); _queueProviders = queueProviders ?? throw new ArgumentNullException(nameof(queueProviders)); }
/// <summary> /// Tells the bootstrapper to use PostgreSQL as a job storage /// with the given options, that can be accessed using the specified /// connection string or its name. /// </summary> /// <param name="configuration">Configuration</param> /// <param name="nameOrConnectionString">Connection string or its name</param> /// <param name="connectionSetup">Optional setup action to apply to created connections</param> /// <param name="options">Advanced options</param> public static IGlobalConfiguration <PostgreSqlStorage> UsePostgreSqlStorage( this IGlobalConfiguration configuration, string nameOrConnectionString, Action <NpgsqlConnection> connectionSetup, PostgreSqlStorageOptions options) { var storage = new PostgreSqlStorage(nameOrConnectionString, connectionSetup, options); return(configuration.UseStorage(storage)); }
/// <summary> /// Tells the bootstrapper to use PostgreSQL as a job storage /// with the given options, that can be accessed using the specified /// connection string or its name. /// </summary> /// <param name="configuration">Configuration</param> /// <param name="nameOrConnectionString">Connection string or its name</param> /// <param name="options">Advanced options</param> public static PostgreSqlStorage UsePostgreSqlStorage( this IGlobalConfiguration configuration, string nameOrConnectionString, PostgreSqlStorageOptions options) { var storage = new PostgreSqlStorage(nameOrConnectionString, options); configuration.UseStorage(storage); return(storage); }
public StorageConnection( IConnectionProvider connectionProvider, IJobQueue queue, PostgreSqlStorageOptions options) { Guard.ThrowIfNull(connectionProvider, nameof(connectionProvider)); Guard.ThrowIfNull(queue, nameof(queue)); Guard.ThrowIfNull(options, nameof(options)); _connectionProvider = connectionProvider; _queue = queue; }
public void PostgreSqlDistributedLock_Init_Transaction(string resource, TimeSpan timeout, IDbConnection connection, PostgreSqlStorageOptions options) { Stopwatch lockAcquiringTime = new Stopwatch(); lockAcquiringTime.Start(); bool tryAcquireLock = true; while (tryAcquireLock) { try { int rowsAffected = -1; using (var trx = _connection.BeginTransaction(IsolationLevel.RepeatableRead)) { rowsAffected = _connection.Execute(@" INSERT INTO """ + _options.SchemaName + @""".""lock""(""resource"") SELECT @resource WHERE NOT EXISTS ( SELECT 1 FROM """ + _options.SchemaName + @""".""lock"" WHERE ""resource"" = @resource ); ", new { resource = resource }, trx); trx.Commit(); } if (rowsAffected > 0) return; } catch (Exception) { } if (lockAcquiringTime.ElapsedMilliseconds > timeout.TotalMilliseconds) tryAcquireLock = false; else { int sleepDuration = (int) (timeout.TotalMilliseconds - lockAcquiringTime.ElapsedMilliseconds); if (sleepDuration > 1000) sleepDuration = 1000; if (sleepDuration > 0) Thread.Sleep(sleepDuration); else tryAcquireLock = false; } } throw new PostgreSqlDistributedLockException( String.Format( "Could not place a lock on the resource '{0}': {1}.", _resource, "Lock timeout")); }
public PostgreSqlFetchedJob( PostgreSqlStorage storage, PostgreSqlStorageOptions options, long id, string jobId, string queue) { _storage = storage ?? throw new ArgumentNullException(nameof(storage)); _options = options ?? throw new ArgumentNullException(nameof(options)); Id = id; JobId = jobId ?? throw new ArgumentNullException(nameof(jobId)); Queue = queue ?? throw new ArgumentNullException(nameof(queue)); }
public PostgreSqlWriteOnlyTransaction( NpgsqlConnection connection, PostgreSqlStorageOptions options, PersistentJobQueueProviderCollection queueProviders) { if (connection == null) throw new ArgumentNullException("connection"); if (queueProviders == null) throw new ArgumentNullException("queueProviders"); if (options == null) throw new ArgumentNullException("options"); _connection = connection; ; _options = options; _queueProviders = queueProviders; }
public PostgreSqlJobQueueMonitoringApi(IDbConnection connection, PostgreSqlStorageOptions options) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } _connection = connection; _options = options; }
public PostgreSqlMonitoringApi( string connectionString, PostgreSqlStorageOptions options, PersistentJobQueueProviderCollection queueProviders) { if (options == null) { throw new ArgumentNullException("options"); } _connectionString = connectionString; _queueProviders = queueProviders; _options = options; }
public PostgreSqlJobQueue(IDbConnection connection, PostgreSqlStorageOptions options) { if (options == null) { throw new ArgumentNullException("options"); } if (connection == null) { throw new ArgumentNullException("connection"); } _options = options; _connection = connection; }
public PostgreSqlConnection( NpgsqlConnection connection, PersistentJobQueueProviderCollection queueProviders, PostgreSqlStorageOptions options, bool ownsConnection) { if (connection == null) throw new ArgumentNullException("connection"); if (queueProviders == null) throw new ArgumentNullException("queueProviders"); if (options == null) throw new ArgumentNullException("options"); _connection = connection; _queueProviders = queueProviders; _options = options; OwnsConnection = ownsConnection; }
public ExpirationManager(PostgreSqlStorage storage, PostgreSqlStorageOptions options, TimeSpan checkInterval) { if (storage == null) { throw new ArgumentNullException("storage"); } if (options == null) { throw new ArgumentNullException("options"); } _options = options; _storage = storage; _checkInterval = checkInterval; }
public PostgreSqlDistributedLock(string resource, TimeSpan timeout, IDbConnection connection, PostgreSqlStorageOptions options) { if (string.IsNullOrEmpty(resource)) throw new ArgumentNullException(nameof(resource)); if (connection == null) throw new ArgumentNullException(nameof(connection)); if (options == null) throw new ArgumentNullException(nameof(options)); _resource = resource; _connection = connection; _options = options; if (_options.UseNativeDatabaseTransactions) PostgreSqlDistributedLock_Init_Transaction(resource, timeout, connection, options); else PostgreSqlDistributedLock_Init_UpdateCount(resource, timeout, connection, options); }
public PostgreSqlStorage(NpgsqlConnection existingConnection) { if (existingConnection == null) { throw new ArgumentNullException(nameof(existingConnection)); } var connectionStringBuilder = new NpgsqlConnectionStringBuilder(existingConnection.ConnectionString); if (connectionStringBuilder.Enlist) { throw new ArgumentException( "Npgsql is not fully compatible with TransactionScope yet, only connections without Enlist = true are accepted."); } _existingConnection = existingConnection; _options = new PostgreSqlStorageOptions(); InitializeQueueProviders(); }
public PostgreSqlFetchedJob( IDbConnection connection, PostgreSqlStorageOptions options, int id, string jobId, string queue) { if (connection == null) throw new ArgumentNullException("connection"); if (jobId == null) throw new ArgumentNullException("jobId"); if (queue == null) throw new ArgumentNullException("queue"); if (options == null) throw new ArgumentNullException("options"); _connection = connection; _options = options; Id = id; JobId = jobId; Queue = queue; }
/// <summary> /// Initializes PostgreSqlStorage with the provided connection string and the provided PostgreSqlStorageOptions. /// </summary> /// <param name="connectionString">A Postgres connection string</param> /// <param name="options"></param> /// <exception cref="ArgumentNullException"><paramref name="connectionString"/> is null.</exception> /// <exception cref="ArgumentNullException"><paramref name="options"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="connectionString"/> is not valid PostgreSql connection string.</exception> public PostgreSqlStorage(string connectionString, PostgreSqlStorageOptions options) { Guard.ThrowIfNull(connectionString, nameof(connectionString)); Guard.ThrowIfNull(options, nameof(options)); Guard.ThrowIfConnectionStringIsInvalid(connectionString); _options = options; var builder = new NpgsqlConnectionStringBuilder(connectionString); _connectionProvider = CreateConnectionProvider(connectionString, builder); var queue = new JobQueue(_connectionProvider, _options); _storageConnection = new StorageConnection(_connectionProvider, queue, _options); _monitoringApi = new MonitoringApi(_connectionProvider); _storageInfo = $"PostgreSQL Server: Host: {builder.Host}, DB: {builder.Database}, Schema: {builder.SearchPath}, Pool: {_connectionProvider.GetType().Name}"; PrepareSchemaIfNecessary(builder.SearchPath); }
/// <summary> /// Initializes PostgreSqlStorage from the provided PostgreSqlStorageOptions and either the provided connection /// string or the connection string with provided name pulled from the application config file. /// </summary> /// <param name="nameOrConnectionString">Either a SQL Server connection string or the name of /// a SQL Server connection string located in the connectionStrings node in the application config</param> /// <param name="options"></param> /// <exception cref="ArgumentNullException"><paramref name="nameOrConnectionString"/> argument is null.</exception> /// <exception cref="ArgumentNullException"><paramref name="options"/> argument is null.</exception> /// <exception cref="ArgumentException"><paramref name="nameOrConnectionString"/> argument is neither /// a valid SQL Server connection string nor the name of a connection string in the application /// config file.</exception> public PostgreSqlStorage(string nameOrConnectionString, PostgreSqlStorageOptions options) { if (nameOrConnectionString == null) { throw new ArgumentNullException(nameof(nameOrConnectionString)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } _options = options; if (IsConnectionString(nameOrConnectionString)) { _connectionString = nameOrConnectionString; } #if (NETSTANDARD2_0) #else else if (IsConnectionStringInConfiguration(nameOrConnectionString)) { _connectionString = ConfigurationManager.ConnectionStrings[nameOrConnectionString].ConnectionString; } #endif else { throw new ArgumentException( $"Could not find connection string with name '{nameOrConnectionString}' in application config file"); } if (options.PrepareSchemaIfNecessary) { using (var connection = CreateAndOpenConnection()) { PostgreSqlObjectsInstaller.Install(connection, options.SchemaName); } } InitializeQueueProviders(); }
/// <summary> /// Initializes PostgreSqlStorage from the provided PostgreSqlStorageOptions and either the provided connection /// string or the connection string with provided name pulled from the application config file. /// </summary> /// <param name="nameOrConnectionString">Either a SQL Server connection string or the name of /// a SQL Server connection string located in the connectionStrings node in the application config</param> /// <param name="options"></param> /// <exception cref="ArgumentNullException"><paramref name="nameOrConnectionString"/> argument is null.</exception> /// <exception cref="ArgumentNullException"><paramref name="options"/> argument is null.</exception> /// <exception cref="ArgumentException"><paramref name="nameOrConnectionString"/> argument is neither /// a valid SQL Server connection string nor the name of a connection string in the application /// config file.</exception> public PostgreSqlStorage(string nameOrConnectionString, PostgreSqlStorageOptions options) { if (nameOrConnectionString == null) { throw new ArgumentNullException("nameOrConnectionString"); } if (options == null) { throw new ArgumentNullException("options"); } _options = options; if (IsConnectionString(nameOrConnectionString)) { _connectionString = nameOrConnectionString; } else if (IsConnectionStringInConfiguration(nameOrConnectionString)) { _connectionString = ConfigurationManager.ConnectionStrings[nameOrConnectionString].ConnectionString; } else { throw new ArgumentException( string.Format("Could not find connection string with name '{0}' in application config file", nameOrConnectionString)); } if (options.PrepareSchemaIfNecessary) { using (var connection = CreateAndOpenConnection()) { PostgreSqlObjectsInstaller.Install(connection); } } var defaultQueueProvider = new PostgreSqlJobQueueProvider(options); QueueProviders = new PersistentJobQueueProviderCollection(defaultQueueProvider); }
public PostgreSqlWriteOnlyTransaction( NpgsqlConnection connection, PostgreSqlStorageOptions options, PersistentJobQueueProviderCollection queueProviders) { if (connection == null) { throw new ArgumentNullException("connection"); } if (queueProviders == null) { throw new ArgumentNullException("queueProviders"); } if (options == null) { throw new ArgumentNullException("options"); } _connection = connection; ; _options = options; _queueProviders = queueProviders; }
public PostgreSqlConnection( NpgsqlConnection connection, PersistentJobQueueProviderCollection queueProviders, PostgreSqlStorageOptions options, bool ownsConnection) { if (connection == null) { throw new ArgumentNullException(nameof(connection)); } if (queueProviders == null) { throw new ArgumentNullException(nameof(queueProviders)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } _connection = connection; _queueProviders = queueProviders; _options = options; OwnsConnection = ownsConnection; }
private static void PostgreSqlDistributedLock_Init_Transaction(string resource, TimeSpan timeout, IDbConnection connection, PostgreSqlStorageOptions options) { var lockAcquiringTime = Stopwatch.StartNew(); bool tryAcquireLock = true; while (tryAcquireLock) { TryRemoveDeadlock(resource, connection, options); try { int rowsAffected = -1; using (var trx = connection.BeginTransaction(IsolationLevel.RepeatableRead)) { rowsAffected = connection.Execute($@" INSERT INTO ""{options.SchemaName}"".""lock""(""resource"", ""acquired"") SELECT @resource, @acquired WHERE NOT EXISTS ( SELECT 1 FROM ""{options.SchemaName}"".""lock"" WHERE ""resource"" = @resource ); ", new { resource = resource, acquired = DateTime.UtcNow }, trx); trx.Commit(); } if (rowsAffected > 0) { return; } } catch { } if (lockAcquiringTime.ElapsedMilliseconds > timeout.TotalMilliseconds) { tryAcquireLock = false; } else { int sleepDuration = (int)(timeout.TotalMilliseconds - lockAcquiringTime.ElapsedMilliseconds); if (sleepDuration > 1000) { sleepDuration = 1000; } if (sleepDuration > 0) { Thread.Sleep(sleepDuration); } else { tryAcquireLock = false; } } } throw new PostgreSqlDistributedLockException( $"Could not place a lock on the resource \'{resource}\': Lock timeout."); }
public PostgreSqlJobQueueProvider(PostgreSqlStorageOptions options) { if (options == null) throw new ArgumentNullException("options"); _options = options; }
private static void PostgreSqlDistributedLock_Init_UpdateCount(string resource, TimeSpan timeout, IDbConnection connection, PostgreSqlStorageOptions options) { var lockAcquiringTime = Stopwatch.StartNew(); bool tryAcquireLock = true; while (tryAcquireLock) { try { connection.Execute($@" INSERT INTO ""{options.SchemaName}"".""lock""(""resource"", ""updatecount"", ""acquired"") SELECT @resource, 0, @acquired WHERE NOT EXISTS ( SELECT 1 FROM ""{options.SchemaName}"".""lock"" WHERE ""resource"" = @resource ); ", new { resource = resource, acquired = DateTime.UtcNow }); } catch (Exception) { } int rowsAffected = connection.Execute($@"UPDATE ""{options.SchemaName}"".""lock"" SET ""updatecount"" = 1 WHERE ""updatecount"" = 0"); if (rowsAffected > 0) { return; } if (lockAcquiringTime.ElapsedMilliseconds > timeout.TotalMilliseconds) { tryAcquireLock = false; } else { int sleepDuration = (int)(timeout.TotalMilliseconds - lockAcquiringTime.ElapsedMilliseconds); if (sleepDuration > 1000) { sleepDuration = 1000; } if (sleepDuration > 0) { Thread.Sleep(sleepDuration); } else { tryAcquireLock = false; } } } throw new PostgreSqlDistributedLockException( $"Could not place a lock on the resource '{resource}': Lock timeout."); }
private static void TryRemoveDeadlock(string resource, IDbConnection connection, PostgreSqlStorageOptions options) { try { using (var transaction = connection.BeginTransaction(IsolationLevel.RepeatableRead)) { int affected = -1; affected = connection.Execute($@"DELETE FROM ""{options.SchemaName}"".""lock"" WHERE ""resource"" = @resource AND ""acquired"" < @timeout", new { resource = resource, timeout = DateTime.UtcNow - options.DistributedLockTimeout }); transaction.Commit(); } } catch { } }
public void PostgreSqlDistributedLock_Init_UpdateCount(string resource, TimeSpan timeout, IDbConnection connection, PostgreSqlStorageOptions options) { Stopwatch lockAcquiringTime = new Stopwatch(); lockAcquiringTime.Start(); bool tryAcquireLock = true; while (tryAcquireLock) { try { _connection.Execute(@" INSERT INTO """ + _options.SchemaName + @""".""lock""(""resource"", ""updatecount"") SELECT @resource, 0 WHERE NOT EXISTS ( SELECT 1 FROM """ + _options.SchemaName + @""".""lock"" WHERE ""resource"" = @resource ); ", new { resource = resource }); } catch (Exception) { } int rowsAffected = _connection.Execute(@"UPDATE """ + _options.SchemaName + @""".""lock"" SET ""updatecount"" = 1 WHERE ""updatecount"" = 0"); if (rowsAffected > 0) return; if (lockAcquiringTime.ElapsedMilliseconds > timeout.TotalMilliseconds) tryAcquireLock = false; else { int sleepDuration = (int)(timeout.TotalMilliseconds - lockAcquiringTime.ElapsedMilliseconds); if (sleepDuration > 1000) sleepDuration = 1000; if (sleepDuration > 0) Thread.Sleep(sleepDuration); else tryAcquireLock = false; } } throw new PostgreSqlDistributedLockException( String.Format( "Could not place a lock on the resource '{0}': {1}.", _resource, "Lock timeout")); }
public ExpirationManager(PostgreSqlStorage storage, PostgreSqlStorageOptions options) : this(storage, options, TimeSpan.FromHours(1)) { }
private static void PostgreSqlDistributedLock_Init_UpdateCount(string resource, TimeSpan timeout, IDbConnection connection, PostgreSqlStorageOptions options) { var lockAcquiringTime = Stopwatch.StartNew(); bool tryAcquireLock = true; while (tryAcquireLock) { try { connection.Execute($@" INSERT INTO ""{options.SchemaName}"".""lock""(""resource"", ""updatecount"", ""acquired"") SELECT @resource, 0, @acquired WHERE NOT EXISTS ( SELECT 1 FROM ""{options.SchemaName}"".""lock"" WHERE ""resource"" = @resource ); ", new { resource = resource, acquired = DateTime.UtcNow }); } catch (Exception) { } int rowsAffected = connection.Execute($@"UPDATE ""{options.SchemaName}"".""lock"" SET ""updatecount"" = 1 WHERE ""updatecount"" = 0"); if (rowsAffected > 0) return; if (lockAcquiringTime.ElapsedMilliseconds > timeout.TotalMilliseconds) tryAcquireLock = false; else { int sleepDuration = (int)(timeout.TotalMilliseconds - lockAcquiringTime.ElapsedMilliseconds); if (sleepDuration > 1000) sleepDuration = 1000; if (sleepDuration > 0) Thread.Sleep(sleepDuration); else tryAcquireLock = false; } } throw new PostgreSqlDistributedLockException( $"Could not place a lock on the resource '{resource}': Lock timeout."); }
/// <summary> /// Initializes a new instance of the <see cref="PostgreSqlStorage"/> class with /// explicit instance of the <see cref="NpgsqlConnection"/> class that will be used /// to query the data. /// </summary> /// <param name="existingConnection">Existing connection</param> /// <param name="options">PostgreSqlStorageOptions</param> public PostgreSqlStorage(NpgsqlConnection existingConnection, PostgreSqlStorageOptions options) { if (existingConnection == null) throw new ArgumentNullException(nameof(existingConnection)); if (options == null) throw new ArgumentNullException(nameof(options)); var connectionStringBuilder = new NpgsqlConnectionStringBuilder(existingConnection.ConnectionString); if (connectionStringBuilder.Enlist) throw new ArgumentException( "Npgsql is not fully compatible with TransactionScope yet, only connections without Enlist = true are accepted."); _existingConnection = existingConnection; _options = options; InitializeQueueProviders(); }