Пример #1
0
        /// <summary>
        /// Registers the specified shellContext as dependent such that it is also released when the current shell context is released.
        /// </summary>
        public void AddDependentShell(ShellContext shellContext)
        {
            // If the dependent is released, nothing to do.
            if (shellContext.Released)
            {
                return;
            }

            // If the dependency is already released.
            if (_released)
            {
                // The dependent is released immediately.
                shellContext.Release();
                return;
            }

            lock (_synLock)
            {
                if (_dependents == null)
                {
                    _dependents = new List <WeakReference <ShellContext> >();
                }

                // Remove any previous instance that represent the same tenant in case it has been released (restarted).
                _dependents.RemoveAll(x => !x.TryGetTarget(out var shell) || shell.Settings.Name == shellContext.Settings.Name);

                _dependents.Add(new WeakReference <ShellContext>(shellContext));
            }
        }
        /// <summary>
        /// Tries to acquire a lock for shell activation, a local lock if it is initializing, otherwise a distributed lock.
        /// </summary>
        public static Task <(ILocker locker, bool locked)> TryAcquireShellActivateLockAsync(this ShellContext shellContext)
        {
            // If the shell is initializing, force the usage of a local lock.
            var lockService = shellContext.Settings.State == TenantState.Initializing
                ? (ILock)shellContext.ServiceProvider.GetRequiredService <ILocalLock>()
                : shellContext.ServiceProvider.GetRequiredService <IDistributedLock>();

            TimeSpan timeout, expiration;

            if (lockService is ILocalLock)
            {
                // If it is a local lock, don't use any timeout and expiration.
                timeout = expiration = TimeSpan.MaxValue;
            }
            else
            {
                // If it is a distributed lock, use the configured timeout and expiration.
                var options = shellContext.ServiceProvider.GetRequiredService <IOptions <ShellContextOptions> >();
                timeout    = TimeSpan.FromMilliseconds(options.Value.ShellActivateLockTimeout);
                expiration = TimeSpan.FromMilliseconds(options.Value.ShellActivateLockExpiration);
            }

            return(lockService.TryAcquireLockAsync("SHELL_ACTIVATE_LOCK", timeout, expiration));
        }