public PortGPIB(int BoardNumber, Address GPIBAddress, TimeoutValue Timeout) { dev = new Device(BoardNumber, GPIBAddress) { IOTimeout = Timeout }; }
public RedLockTimeouts( TimeoutValue expiry, TimeoutValue minValidityTime) { this.Expiry = expiry; this.MinValidityTime = minValidityTime; }
private async Task <bool> DoKeepaliveAsync(TimeoutValue keepaliveCadence, CancellationToken stateChangedToken) { await Task.Delay(keepaliveCadence.InMilliseconds, stateChangedToken).TryAwait(); if (stateChangedToken.IsCancellationRequested) { return(true); } // retrieve only after the delay to avoid this reference longer than needed if (!this._weakConnection.TryGetTarget(out var connection)) { return(false); } // We do a zero-wait try-lock here because if the connection is in-use then someone is querying with it. In that case, // There's no need for us to run a keepalive query. Since we are using zero timeout, we don't bother to pass the cancellationToken; // this saves us from having to handle cancellation exceptions using var connectionLockHandle = await this._connectionLock.TryAcquireAsync(TimeSpan.Zero, CancellationToken.None).ConfigureAwait(false); if (connectionLockHandle != null) { using var command = connection.CreateCommand(); command.SetCommandText("SELECT 0 /* DistributedLock connection keepalive */"); // Since this query is very fast and non-blocking, we don't bother trying to cancel it. This avoids having // to deal with the overhead of throwing exceptions within ExecuteNonQueryAsync() await command.ExecuteNonQueryAsync(CancellationToken.None, disallowAsyncCancellation : false, isConnectionMonitoringQuery : true).AsTask().TryAwait(); } return(true); }
public async ValueTask <IDistributedSynchronizationHandle?> TryAcquireAsync <TLockCookie>( TimeoutValue timeout, IDbSynchronizationStrategy <TLockCookie> strategy, CancellationToken cancellationToken, IDistributedSynchronizationHandle?contextHandle) where TLockCookie : class { IDistributedSynchronizationHandle?result = null; IAsyncDisposable?connectionResource = null; try { DatabaseConnection connection; if (contextHandle != null) { connection = GetContextHandleConnection <TLockCookie>(contextHandle); } else { connectionResource = connection = this._connectionFactory(); if (connection.IsExernallyOwned) { if (!connection.CanExecuteQueries) { throw new InvalidOperationException("The connection and/or transaction are disposed or closed"); } } else { await connection.OpenAsync(cancellationToken).ConfigureAwait(false); if (this._transactionScopedIfPossible) // for an internally-owned connection, we must create the transaction { await connection.BeginTransactionAsync().ConfigureAwait(false); } } } var lockCookie = await strategy.TryAcquireAsync(connection, this._name, timeout, cancellationToken).ConfigureAwait(false); if (lockCookie != null) { result = new Handle <TLockCookie>(connection, strategy, this._name, lockCookie, transactionScoped: this._transactionScopedIfPossible && connection.HasTransaction, connectionResource); if (!this._keepaliveCadence.IsInfinite) { connection.SetKeepaliveCadence(this._keepaliveCadence); } } } finally { // if we fail to acquire or throw, make sure to clean up the connection if (result == null && connectionResource != null) { await connectionResource.DisposeAsync().ConfigureAwait(false); } } return(result); }
public AgPowerSupply(byte address, TimeoutValue timeout) : this() { settings = AgSettings.DefaultSettings; settings.GpibAddress = address; settings.GpibTimeout = timeout; this.InternalConnect( ); }
public TimeoutTask(TimeoutValue timeout, CancellationToken cancellationToken) { this._cleanupTokenSource = new CancellationTokenSource(); this._linkedTokenSource = cancellationToken.CanBeCanceled ? CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, this._cleanupTokenSource.Token) : null; this.Task = Task.Delay(timeout.TimeSpan, this._linkedTokenSource?.Token ?? this._cleanupTokenSource.Token); }
public void SetTimeout(TimeoutValue operationTimeout) { this._command.CommandTimeout = operationTimeout.IsInfinite // use the infinite timeout of 0 // (see https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.commandtimeout%28v=vs.110%29.aspx) ? 0 // command timeout is in seconds. We always wait at least the given timeout plus a buffer : operationTimeout.InSeconds + 30; }
public async ValueTask <Result> TryAcquireAsync <TLockCookie>( string name, TimeoutValue timeout, IDbSynchronizationStrategy <TLockCookie> strategy, TimeoutValue keepaliveCadence, CancellationToken cancellationToken, bool opportunistic) where TLockCookie : class { using var mutextHandle = await this._mutex.TryAcquireAsync(opportunistic?TimeSpan.Zero : Timeout.InfiniteTimeSpan, cancellationToken).ConfigureAwait(false); if (mutextHandle == null) { // mutex wasn't free, so just give up Invariant.Require(opportunistic); // The current lock is busy so we allow retry but on a different lock instance. We can't safely dispose // since we never acquired the mutex so we can't check _heldLocks return(new Result(MultiplexedConnectionLockRetry.Retry, canSafelyDispose: false)); } try { if (this._heldLocksToKeepaliveCadences.ContainsKey(name)) { // we won't try to hold the same lock twice on one connection. At some point, we could // support this case in-memory using a counter for each multiply-held lock name and being careful // with modes return(this.GetFailureResultNoLock(isAlreadyHeld: true, opportunistic, timeout)); } if (!this._connection.CanExecuteQueries) { await this._connection.OpenAsync(cancellationToken).ConfigureAwait(false); } var lockCookie = await strategy.TryAcquireAsync(this._connection, name, opportunistic?TimeSpan.Zero : timeout, cancellationToken).ConfigureAwait(false); if (lockCookie != null) { var handle = new ManagedFinalizationDistributedLockHandle(new Handle <TLockCookie>(this, strategy, name, lockCookie)); this._heldLocksToKeepaliveCadences.Add(name, keepaliveCadence); if (!keepaliveCadence.IsInfinite) { this.SetKeepaliveCadenceNoLock(); } return(new Result(handle)); } // we failed to acquire the lock, so we should retry if we were being opportunistic and artificially // shortened the timeout return(this.GetFailureResultNoLock(isAlreadyHeld: false, opportunistic, timeout)); } finally { await this.CloseConnectionIfNeededNoLockAsync().ConfigureAwait(false); } }
public AMP_FL8611(byte address, TimeoutValue timeout) : this() { settings = AgSettings.DefaultSettings; settings.GpibAddress = address; settings.GpibTimeout = timeout; this.gpib = new GpibDriver(this.settings.GpibAddress); gpib.GetIdentity( ); }
async ValueTask <OracleDistributedReaderWriterLockUpgradeableHandle?> IInternalDistributedUpgradeableReaderWriterLock <OracleDistributedReaderWriterLockHandle, OracleDistributedReaderWriterLockUpgradeableHandle> .InternalTryAcquireUpgradeableReadLockAsync( TimeoutValue timeout, CancellationToken cancellationToken) { var innerHandle = await this._internalLock .TryAcquireAsync(timeout, OracleDbmsLock.UpdateLock, cancellationToken, contextHandle : null).ConfigureAwait(false); return(innerHandle != null ? new OracleDistributedReaderWriterLockUpgradeableHandle(innerHandle, this._internalLock) : null); }
async ValueTask <OracleDistributedReaderWriterLockHandle?> IInternalDistributedReaderWriterLock <OracleDistributedReaderWriterLockHandle> .InternalTryAcquireAsync( TimeoutValue timeout, CancellationToken cancellationToken, bool isWrite) { var innerHandle = await this._internalLock .TryAcquireAsync(timeout, isWrite?OracleDbmsLock.ExclusiveLock : OracleDbmsLock.SharedLock, cancellationToken, contextHandle : null).ConfigureAwait(false); return(innerHandle != null ? new OracleDistributedReaderWriterLockNonUpgradeableHandle(innerHandle) : null); }
private DatabaseCommand CreateAcquireCommand( DatabaseConnection connection, string lockName, TimeoutValue timeout, out IDbDataParameter returnValue) { var command = connection.CreateCommand(); if (connection.IsExernallyOwned || this._isUpgrade) { returnValue = command.AddParameter("Result", type: DbType.Int32, direction: ParameterDirection.Output); const string CurrentOwnerMode = "APPLOCK_MODE('public', @Resource, @LockOwner)", GetAppLock = "EXEC @Result = dbo.sp_getapplock @Resource=@Resource, @LockMode=@LockMode, @LockOwner=@LockOwner, @LockTimeout=@LockTimeout, @DbPrincipal='public'"; var alternateOwnerHasLockCheck = connection.IsExernallyOwned && connection.HasTransaction ? " OR APPLOCK_MODE('public', @Resource, 'Session') != 'NoLock'" : string.Empty; if (this._isUpgrade) { command.SetCommandText( $@"DECLARE @Mode NVARCHAR(32) = {CurrentOwnerMode} IF @Mode = 'NoLock' SET @Result = {InvalidUpgradeExitCode} ELSE IF @Mode != '{GetModeString(Mode.Update)}'{alternateOwnerHasLockCheck} SET @Result = {AlreadyHeldExitCode} ELSE {GetAppLock}" ); } else { command.SetCommandText( $@"IF {CurrentOwnerMode} != 'NoLock'{alternateOwnerHasLockCheck} SET @Result = {AlreadyHeldExitCode} ELSE {GetAppLock}" ); } } else { returnValue = command.AddParameter(type: DbType.Int32, direction: ParameterDirection.ReturnValue); command.SetCommandText("dbo.sp_getapplock"); command.SetCommandType(CommandType.StoredProcedure); } command.SetTimeout(timeout); command.AddParameter("Resource", lockName); command.AddParameter("LockMode", GetModeString(this._mode)); command.AddParameter("LockOwner", connection.HasTransaction ? "Transaction" : "Session"); command.AddParameter("LockTimeout", timeout.InMilliseconds); return(command); }
/// <summary> /// The lock expiry determines how long the lock will be held without being extended. However, since it takes some amount /// of time to acquire the lock, we will not have all of expiry available upon acquisition. /// /// This value sets a minimum amount which we'll be guaranteed to have left once acquisition completes. /// /// Defaults to 90% of the specified lock expiry. /// </summary> public RedisDistributedSynchronizationOptionsBuilder MinValidityTime(TimeSpan minValidityTime) { var minValidityTimeoutValue = new TimeoutValue(minValidityTime, nameof(minValidityTime)); if (minValidityTimeoutValue.IsZero) { throw new ArgumentOutOfRangeException(nameof(minValidityTime), minValidityTime, "may not be zero"); } this._minValidityTime = minValidityTimeoutValue; return(this); }
/// <summary> /// Specifies how long the lock will last, absent auto-extension. Because auto-extension exists, /// this value generally will have little effect on program behavior. However, making the expiry longer means that /// auto-extension requests can occur less frequently, saving resources. On the other hand, when a lock is abandoned /// without explicit release (e. g. if the holding process crashes), the expiry determines how long other processes /// would need to wait in order to acquire it. /// /// Defaults to 30s. /// </summary> public RedisDistributedSynchronizationOptionsBuilder Expiry(TimeSpan expiry) { var expiryTimeoutValue = new TimeoutValue(expiry, nameof(expiry)); if (expiryTimeoutValue.IsInfinite || expiryTimeoutValue.CompareTo(MinimumExpiry) < 0) { throw new ArgumentOutOfRangeException(nameof(expiry), expiry, $"Must be >= {MinimumExpiry.TimeSpan} and < ∞"); } this._expiry = expiryTimeoutValue; return(this); }
public DedicatedConnectionOrTransactionDbDistributedLock( string name, Func <DatabaseConnection> connectionFactory, bool useTransaction, TimeoutValue keepaliveCadence) { this._name = name; this._connectionFactory = connectionFactory; this._scopeToOwnedTransaction = useTransaction; this._keepaliveCadence = keepaliveCadence; }
/// <summary> /// Constructs a lock with the given <paramref name="name"/>. /// /// <paramref name="abandonmentCheckCadence"/> specifies how frequently we refresh our <see cref="Semaphore"/> object in case it is abandoned by /// its original owner. The default is 2s. /// /// Unless <paramref name="exactName"/> is specified, <paramref name="name"/> will be escaped/hashed to ensure name validity. /// </summary> public WaitHandleDistributedSemaphore(string name, int maxCount, TimeSpan?abandonmentCheckCadence = null, bool exactName = false) { if (maxCount < 1) { throw new ArgumentOutOfRangeException(nameof(maxCount), maxCount, "must be positive"); } this.Name = DistributedWaitHandleHelpers.ValidateAndFinalizeName(name, exactName); this.MaxCount = maxCount; this._abandonmentCheckCadence = DistributedWaitHandleHelpers.ValidateAndFinalizeAbandonmentCheckCadence(abandonmentCheckCadence); }
public GpibDriver(byte primaryAddress, TimeoutValue timeout) { device_ = null; int boardId = 0; byte secondaryAddress = 0; device_ = new Device(boardId, primaryAddress, secondaryAddress, timeout); device_.SynchronizeCallbacks = true; device_.DefaultBufferSize = 1048576; device_.EndOfStringCharacter = 0x0A; device_.TerminateReadOnEndOfString = true; }
public RedLockHandle( IRedLockExtensibleSynchronizationPrimitive primitive, Dictionary <IDatabase, Task <bool> > tryAcquireTasks, TimeoutValue extensionCadence, TimeoutValue expiry) { this._primitive = primitive; this._tryAcquireTasks = tryAcquireTasks; this._extensionCadence = extensionCadence; this._expiry = expiry; // important to set this last, since the monitor constructor will read other fields of this this._monitor = new LeaseMonitor(this); }
async ValueTask <EventWaitHandleDistributedLockHandle?> IInternalDistributedLock <EventWaitHandleDistributedLockHandle> .InternalTryAcquireAsync( TimeoutValue timeout, CancellationToken cancellationToken) { var @event = await DistributedWaitHandleHelpers.CreateAndWaitAsync( createHandle : this.CreateEvent, abandonmentCheckCadence : this._abandonmentCheckCadence, timeout : timeout, cancellationToken : cancellationToken ).ConfigureAwait(false); return(@event != null ? new EventWaitHandleDistributedLockHandle(@event) : null); }
/// <summary> /// Specifies how long the lease will last, absent auto-renewal. /// /// If auto-renewal is enabled (the default), then a shorter duration means more frequent auto-renewal requests, /// while an infinite duration means no auto-renewal requests. Furthermore, if the lease-holding process were to /// exit without explicitly releasing, then duration determines how long other processes would need to wait in /// order to acquire the lease. /// /// If auto-renewal is disabled, then duration determines how long the lease will be held. /// /// Defaults to 30s. /// </summary> public AzureBlobLeaseOptionsBuilder Duration(TimeSpan duration) { var durationTimeoutValue = new TimeoutValue(duration, nameof(duration)); if (durationTimeoutValue.CompareTo(MinLeaseDuration) < 0 || (!durationTimeoutValue.IsInfinite && durationTimeoutValue.CompareTo(MaxNonInfiniteLeaseDuration) > 0)) { throw new ArgumentOutOfRangeException(nameof(duration), duration, $"Must be infinite or in [{MinLeaseDuration}, {MaxNonInfiniteLeaseDuration}]"); } this._duration = durationTimeoutValue; return(this); }
private void SetKeepaliveCadenceNoLock() { TimeoutValue minCadence = Timeout.InfiniteTimeSpan; foreach (var kvp in this._heldLocksToKeepaliveCadences) { if (kvp.Value.CompareTo(minCadence) < 0) { minCadence = kvp.Value; } } this._connection.SetKeepaliveCadence(minCadence); }
public static async Task <bool> WaitAsync(this Task task, TimeoutValue timeout) { if (!task.IsCompleted) { using var timeoutTask = new TimeoutTask(timeout, CancellationToken.None); if (await Task.WhenAny(task, timeoutTask.Task) != task) { return(false); } } await task; return(true); }
public static bool WaitUntil(Func <bool> condition, TimeoutValue timeout = TimeoutValue.High, double delay = 0.5) { var watch = DateTime.Now.ToEpoch(); while (watch + (int)timeout > DateTime.Now.ToEpoch()) { if (condition()) { return(true); } Thread.Sleep(TimeSpan.FromSeconds(delay)); } return(false); }
/// <summary> /// Configures the <paramref name="sessionTimeout"/> for connections to ZooKeeper. Because the underlying ZooKeeper client periodically renews /// the session, this value generally will not impact behavior. Lower values mean that locks will be released more quickly following a crash /// of the lock-holding process, but also increase the risk that transient connection issues will result in a dropped lock. /// /// Defaults to 20s. /// </summary> public ZooKeeperDistributedSynchronizationOptionsBuilder SessionTimeout(TimeSpan sessionTimeout) { var sessionTimeoutValue = new TimeoutValue(sessionTimeout, nameof(sessionTimeout)); if (sessionTimeoutValue.IsZero) { throw new ArgumentOutOfRangeException(nameof(sessionTimeout), "must be positive"); } if (sessionTimeoutValue.IsInfinite) { throw new ArgumentOutOfRangeException(nameof(sessionTimeout), "must not be infinite"); } this._sessionTimeout = sessionTimeoutValue; return(this); }
public static async ValueTask <bool> ParseExitCodeAsync(int exitCode, TimeoutValue timeout, CancellationToken cancellationToken) { // sp_getapplock exit codes documented at // https://msdn.microsoft.com/en-us/library/ms189823.aspx switch (exitCode) { case 0: case 1: return(true); case TimeoutExitCode: return(false); case -2: // canceled throw new OperationCanceledException(GetErrorMessage(exitCode, "canceled")); case -3: // deadlock throw new DeadlockException(GetErrorMessage(exitCode, "deadlock")); case -999: // parameter / unknown throw new ArgumentException(GetErrorMessage(exitCode, "parameter validation or other error")); case InvalidUpgradeExitCode: // should never happen unless something goes wrong (e. g. user manually releases the lock on an externally-owned connection) throw new InvalidOperationException("Cannot upgrade to an exclusive lock because the update lock is not held"); case AlreadyHeldExitCode: return(timeout.IsZero ? false : timeout.IsInfinite ? throw new DeadlockException("Attempted to acquire a lock that is already held on the same connection") : await WaitThenReturnFalseAsync().ConfigureAwait(false)); default: if (exitCode <= 0) { throw new InvalidOperationException(GetErrorMessage(exitCode, "unknown")); } return(true); // unknown success code } async ValueTask <bool> WaitThenReturnFalseAsync() { await SyncViaAsync.Delay(timeout, cancellationToken).ConfigureAwait(false); return(false); } }
public OptimisticConnectionMultiplexingDbDistributedLock( string name, string connectionString, MultiplexedConnectionLockPool multiplexedConnectionLockPool, TimeoutValue keepaliveCadence) { this._name = name; this._connectionString = connectionString; this._multiplexedConnectionLockPool = multiplexedConnectionLockPool; this._keepaliveCadence = keepaliveCadence; this._fallbackLock = new DedicatedConnectionOrTransactionDbDistributedLock( name, () => this._multiplexedConnectionLockPool.ConnectionFactory(this._connectionString), useTransaction: false, keepaliveCadence: keepaliveCadence ); }
public ValueTask <IDistributedSynchronizationHandle?> TryAcquireAsync <TLockCookie>( TimeoutValue timeout, IDbSynchronizationStrategy <TLockCookie> strategy, CancellationToken cancellationToken, IDistributedSynchronizationHandle?contextHandle) where TLockCookie : class { // cannot multiplex for updates, since we cannot predict whether or not there will be a request to elevate // to an exclusive lock which asks for a long timeout if (!strategy.IsUpgradeable && contextHandle == null) { return(this._multiplexedConnectionLockPool.TryAcquireAsync(this._connectionString, this._name, timeout, strategy, keepaliveCadence: this._keepaliveCadence, cancellationToken)); } // otherwise, fall back to our fallback lock return(this._fallbackLock.TryAcquireAsync(timeout, strategy, cancellationToken, contextHandle)); }
/// <summary> /// Waiting to acquire a lock requires a busy wait that alternates acquire attempts and sleeps. /// This determines how much time is spent sleeping between attempts. Lower values will raise the /// volume of acquire requests under contention but will also raise the responsiveness (how long /// it takes a waiter to notice that a contended the lock has become available). /// /// Specifying a range of values allows the implementation to select an actual value in the range /// at random for each sleep. This helps avoid the case where two clients become "synchronized" /// in such a way that results in one client monopolizing the lock. /// /// The default is [10ms, 800ms] /// </summary> public RedisDistributedSynchronizationOptionsBuilder BusyWaitSleepTime(TimeSpan min, TimeSpan max) { var minTimeoutValue = new TimeoutValue(min, nameof(min)); var maxTimeoutValue = new TimeoutValue(max, nameof(max)); if (minTimeoutValue.IsInfinite) { throw new ArgumentOutOfRangeException(nameof(min), "may not be infinite"); } if (maxTimeoutValue.IsInfinite || maxTimeoutValue.CompareTo(min) < 0) { throw new ArgumentOutOfRangeException(nameof(max), max, "must be non-infinite and greater than " + nameof(min)); } this._minBusyWaitSleepTime = minTimeoutValue; this._maxBusyWaitSleepTime = maxTimeoutValue; return(this); }
async ValueTask <object?> IDbSynchronizationStrategy <object> .TryAcquireAsync( DatabaseConnection connection, string resourceName, TimeoutValue timeout, CancellationToken cancellationToken) { try { return(await this.ExecuteAcquireCommandAsync(connection, resourceName, timeout, cancellationToken).ConfigureAwait(false) ? Cookie : null); } catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested) { // If the command is canceled, I believe there's a slim chance that acquisition just completed before the cancellation went through. // In that case, I'm pretty sure it won't be rolled back. Therefore, to be safe we issue a try-release await ExecuteReleaseCommandAsync(connection, resourceName, isTry : true).ConfigureAwait(false); throw; } }
public void TestProperties() { Assert.IsTrue(default(TimeoutValue).IsZero); Assert.IsFalse(default(TimeoutValue).IsInfinite); Assert.AreEqual(0, default(TimeoutValue).InMilliseconds); Assert.AreEqual(0, default(TimeoutValue).InSeconds); TimeoutValue infinite = Timeout.InfiniteTimeSpan; Assert.IsFalse(infinite.IsZero); Assert.IsTrue(infinite.IsInfinite); Assert.AreEqual(-1, infinite.InMilliseconds); Assert.Throws <InvalidOperationException>(() => infinite.InSeconds.ToString()); TimeoutValue normal = TimeSpan.FromSeconds(10.4); Assert.IsFalse(normal.IsZero); Assert.IsFalse(normal.IsInfinite); Assert.AreEqual(10400, normal.InMilliseconds); Assert.AreEqual(10, normal.InSeconds); }
// // Summary: // Opens and initializes a device and configures it according to the specified // board number, primary address, secondary address, and timeout. // // Parameters: // boardNumber: // Index of the access board for the device. // // primaryAddress: // The primary GPIB address of the device. // // secondaryAddress: // The secondary GPIB address of the device. // // timeoutValue: // The I/O timeout value. // // Exceptions: // NationalInstruments.NI4882.GpibException: // The NI-488.2 driver returns an error as a result of calling this method. // // System.ObjectDisposedException: // This member is called after the NationalInstruments.NI4882.Device.Dispose() // method has been called directly from your code or indirectly through a finalizer. // // System.DllNotFoundException: // The NI-488.2 driver library cannot be found. // // System.EntryPointNotFoundException: // A required operation in the NI-488.2 driver library cannot be found. // // System.ArgumentException: // The primaryAddress parameter is invalid. // -or- // The secondaryAddress parameter is invalid. // // System.InvalidOperationException: // The inner exception is set to the NationalInstruments.NI4882.GpibException // due to one of the following conditions: // A different process owns a lock for the interface. // -or- // boardNumber is within the range 0-99, but the interface board described by // boardNumber is not installed nor properly configured. // -or- // Asynchronous I/O operation in progress. // -or- // The interface board is not Controller-In-Charge. // -or- // DMA error. // -or- // GPIB bus error. // // Remarks: // NationalInstruments.NI4882.Device.SetEndOnWrite is set to true, and NationalInstruments.NI4882.Device.EndOfStringCharacter // is set to 0 during constructor. public Device(int boardNumber, byte primaryAddress, byte secondaryAddress, TimeoutValue timeoutValue);