예제 #1
0
        /// <summary>
        /// Creates a new <see cref="SimpleChannelPool"/> instance.
        /// </summary>
        /// <param name="bootstrap">The <see cref="Bootstrapping.Bootstrap"/> that is used for connections.</param>
        /// <param name="handler">
        /// The <see cref="IChannelPoolHandler"/> that will be notified for the different pool actions.
        /// </param>
        /// <param name="healthChecker">
        /// The <see cref="IChannelHealthChecker"/> that will be used to check if a <see cref="IChannel"/> is still
        /// healthy when obtained from the <see cref="IChannelPool"/>.
        /// </param>
        /// <param name="releaseHealthCheck">
        /// If <c>true</c>, will check channel health before offering back. Otherwise, channel health is only checked
        /// at acquisition time.
        /// </param>
        /// <param name="lastRecentUsed">
        /// If <c>true</c>, <see cref="IChannel"/> selection will be LIFO. If <c>false</c>, it will be FIFO.
        /// </param>
        public SimpleChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, IChannelHealthChecker healthChecker, bool releaseHealthCheck, bool lastRecentUsed)
        {
            if (handler is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.handler);
            }
            if (healthChecker is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.healthChecker);
            }
            if (bootstrap is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.bootstrap);
            }

            Handler            = handler;
            HealthChecker      = healthChecker;
            ReleaseHealthCheck = releaseHealthCheck;

            // Clone the original Bootstrap as we want to set our own handler
            Bootstrap = bootstrap.Clone();
            _         = Bootstrap.Handler(new ActionChannelInitializer <IChannel>(OnChannelInitializing));
            _store    =
                lastRecentUsed
                    ? (IQueue <IChannel>) new CompatibleConcurrentStack <IChannel>()
                    : new CompatibleConcurrentQueue <IChannel>();
        }
예제 #2
0
        public void TestHealthChecker()
        {
            IChannelHealthChecker healthChecker = ChannelActiveHealthChecker.Instance;

            using (var pool = new SimpleChannelPool(new Bootstrap(), new CountingChannelPoolHandler(), healthChecker))
            {
                Assert.Same(healthChecker, pool.HealthChecker);
            }
        }
        /// <summary>
        /// Creates a new channel pool.
        /// </summary>
        /// <param name="bootstrap"> the <seealso cref="Bootstrap"/> used to create promises </param>
        /// <param name="parentPool"> the parent pool providing the channels to the child </param>
        /// <param name="handler"> the <seealso cref="ChannelPoolHandler"/> that will be notified for the different pool actions </param>
        public ChildChannelPool(Bootstrap bootstrap, IChannelPool parentPool, IChannelPoolHandler handler)
        {
            Contract.Requires(handler != null);
            Contract.Requires(parentPool != null);
            Contract.Requires(bootstrap != null);

            this.Handler    = handler;
            this.parentPool = parentPool;
            this.bootstrap  = bootstrap;

            this.HealthChecker      = ChannelActiveHealthChecker.Instance;
            this.ReleaseHealthCheck = true;

            this.store = (IQueue <IChannel>) new CompatibleConcurrentStack <IChannel>();
        }
예제 #4
0
        /// <summary>
        /// Creates a new <see cref="FixedChannelPool"/> instance.
        /// </summary>
        /// <param name="bootstrap">The <see cref="Bootstrap"/> that is used for connections.</param>
        /// <param name="handler">
        /// The <see cref="IChannelPoolHandler"/> that will be notified for the different pool actions.
        /// </param>
        /// <param name="healthChecker">
        /// The <see cref="IChannelHealthChecker"/> that will be used to check if a <see cref="IChannel"/> is still
        /// healthy when obtained from the <see cref="IChannelPool"/>.
        /// </param>
        /// <param name="action">
        /// The <see cref="AcquireTimeoutAction"/> to use or <c>null</c> if none should be used. In this case,
        /// <paramref name="acquireTimeout"/> must also be <c>null</c>.
        /// </param>
        /// <param name="acquireTimeout">
        /// A <see cref="TimeSpan"/> after which an pending acquire must complete, or the
        /// <see cref="AcquireTimeoutAction"/> takes place.
        /// </param>
        /// <param name="maxConnections">
        /// The number of maximal active connections. Once this is reached, new attempts to acquire an
        /// <see cref="IChannel"/> will be delayed until a connection is returned to the pool again.
        /// </param>
        /// <param name="maxPendingAcquires">
        /// The maximum number of pending acquires. Once this is exceeded, acquire attempts will be failed.
        /// </param>
        /// <param name="releaseHealthCheck">If <c>true</c>, will check channel health before offering it back.</param>
        /// <param name="lastRecentUsed">
        /// If <c>true</c>, <see cref="IChannel"/> selection will be LIFO. If <c>false</c>, it will be FIFO.
        /// </param>
        public FixedChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, IChannelHealthChecker healthChecker, AcquireTimeoutAction action, TimeSpan acquireTimeout, int maxConnections, int maxPendingAcquires, bool releaseHealthCheck, bool lastRecentUsed)
            : base(bootstrap, handler, healthChecker, releaseHealthCheck, lastRecentUsed)
        {
            if ((uint)(maxConnections - 1) > SharedConstants.TooBigOrNegative)
            {
                ThrowHelper.ThrowArgumentException_MaxConnections(maxConnections);
            }
            if ((uint)(maxPendingAcquires - 1) > SharedConstants.TooBigOrNegative)
            {
                ThrowHelper.ThrowArgumentException_MaxPendingAcquires(maxPendingAcquires);
            }

            _acquireTimeout = acquireTimeout;
            if (action == AcquireTimeoutAction.None && acquireTimeout == Timeout.InfiniteTimeSpan)
            {
                _timeoutTask = null;
            }
            else if (action == AcquireTimeoutAction.None && acquireTimeout != Timeout.InfiniteTimeSpan)
            {
                ThrowHelper.ThrowArgumentException_Action();
            }
            else if (action != AcquireTimeoutAction.None && acquireTimeout < TimeSpan.Zero)
            {
                ThrowHelper.ThrowArgumentException_AcquireTimeoutMillis(acquireTimeout);
            }
            else
            {
                switch (action)
                {
                case AcquireTimeoutAction.Fail:
                    _timeoutTask = new TimeoutTask(this, OnTimeoutFail);
                    break;

                case AcquireTimeoutAction.New:
                    _timeoutTask = new TimeoutTask(this, OnTimeoutNew);
                    break;

                default:
                    ThrowHelper.ThrowArgumentException_Action(); break;
                }
            }

            _executor           = bootstrap.Group().GetNext();
            _maxConnections     = maxConnections;
            _maxPendingAcquires = maxPendingAcquires;

            _pendingAcquireQueue = PlatformDependent.NewMpscQueue <AcquireTask>();
        }
        /// <summary>
        /// Creates a new <see cref="FixedChannelPool"/> instance.
        /// </summary>
        /// <param name="bootstrap">The <see cref="Bootstrap"/> that is used for connections.</param>
        /// <param name="handler">
        /// The <see cref="IChannelPoolHandler"/> that will be notified for the different pool actions.
        /// </param>
        /// <param name="healthChecker">
        /// The <see cref="IChannelHealthChecker"/> that will be used to check if a <see cref="IChannel"/> is still
        /// healthy when obtained from the <see cref="IChannelPool"/>.
        /// </param>
        /// <param name="action">
        /// The <see cref="AcquireTimeoutAction"/> to use or <c>null</c> if none should be used. In this case,
        /// <paramref name="acquireTimeout"/> must also be <c>null</c>.
        /// </param>
        /// <param name="acquireTimeout">
        /// A <see cref="TimeSpan"/> after which an pending acquire must complete, or the
        /// <see cref="AcquireTimeoutAction"/> takes place.
        /// </param>
        /// <param name="maxConnections">
        /// The number of maximal active connections. Once this is reached, new attempts to acquire an
        /// <see cref="IChannel"/> will be delayed until a connection is returned to the pool again.
        /// </param>
        /// <param name="maxPendingAcquires">
        /// The maximum number of pending acquires. Once this is exceeded, acquire attempts will be failed.
        /// </param>
        /// <param name="releaseHealthCheck">If <c>true</c>, will check channel health before offering it back.</param>
        /// <param name="lastRecentUsed">
        /// If <c>true</c>, <see cref="IChannel"/> selection will be LIFO. If <c>false</c>, it will be FIFO.
        /// </param>
        public FixedChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, IChannelHealthChecker healthChecker, AcquireTimeoutAction action, TimeSpan acquireTimeout, int maxConnections, int maxPendingAcquires, bool releaseHealthCheck, bool lastRecentUsed)
            : base(bootstrap, handler, healthChecker, releaseHealthCheck, lastRecentUsed)
        {
            if (maxConnections < 1)
            {
                throw new ArgumentException($"maxConnections: {maxConnections} (expected: >= 1)");
            }

            if (maxPendingAcquires < 1)
            {
                throw new ArgumentException($"maxPendingAcquires: {maxPendingAcquires} (expected: >= 1)");
            }

            this.acquireTimeout = acquireTimeout;
            if (action == AcquireTimeoutAction.None && acquireTimeout == Timeout.InfiniteTimeSpan)
            {
                this.timeoutTask = null;
            }
            else if (action == AcquireTimeoutAction.None && acquireTimeout != Timeout.InfiniteTimeSpan)
            {
                throw new ArgumentException("action");
            }
            else if (action != AcquireTimeoutAction.None && acquireTimeout < TimeSpan.Zero)
            {
                throw new ArgumentException($"acquireTimeoutMillis: {acquireTimeout} (expected: >= 1)");
            }
            else
            {
                switch (action)
                {
                case AcquireTimeoutAction.Fail:
                    this.timeoutTask = new TimeoutTask(this, this.OnTimeoutFail);
                    break;

                case AcquireTimeoutAction.New:
                    this.timeoutTask = new TimeoutTask(this, this.OnTimeoutNew);
                    break;

                default:
                    throw new ArgumentException("action");
                }
            }

            this.executor           = bootstrap.Group().GetNext();
            this.maxConnections     = maxConnections;
            this.maxPendingAcquires = maxPendingAcquires;
        }
        /// <summary>
        /// Creates a new <see cref="SimpleChannelPool"/> instance.
        /// </summary>
        /// <param name="bootstrap">The <see cref="Bootstrapping.Bootstrap"/> that is used for connections.</param>
        /// <param name="handler">
        /// The <see cref="IChannelPoolHandler"/> that will be notified for the different pool actions.
        /// </param>
        /// <param name="healthChecker">
        /// The <see cref="IChannelHealthChecker"/> that will be used to check if a <see cref="IChannel"/> is still
        /// healthy when obtained from the <see cref="IChannelPool"/>.
        /// </param>
        /// <param name="releaseHealthCheck">
        /// If <c>true</c>, will check channel health before offering back. Otherwise, channel health is only checked
        /// at acquisition time.
        /// </param>
        /// <param name="lastRecentUsed">
        /// If <c>true</c>, <see cref="IChannel"/> selection will be LIFO. If <c>false</c>, it will be FIFO.
        /// </param>
        public SimpleChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, IChannelHealthChecker healthChecker, bool releaseHealthCheck, bool lastRecentUsed)
        {
            Contract.Requires(handler != null);
            Contract.Requires(healthChecker != null);
            Contract.Requires(bootstrap != null);

            this.Handler            = handler;
            this.HealthChecker      = healthChecker;
            this.ReleaseHealthCheck = releaseHealthCheck;

            // Clone the original Bootstrap as we want to set our own handler
            this.Bootstrap = bootstrap.Clone();
            this.Bootstrap.Handler(new ActionChannelInitializer <IChannel>(this.OnChannelInitializing));
            this.store =
                lastRecentUsed
                    ? (IQueue <IChannel>) new CompatibleConcurrentStack <IChannel>()
                    : new CompatibleConcurrentQueue <IChannel>();
        }
예제 #7
0
 /// <summary>
 /// Creates a new <see cref="FixedChannelPool"/> instance.
 /// </summary>
 /// <param name="bootstrap">The <see cref="Bootstrap"/> that is used for connections.</param>
 /// <param name="handler">
 /// The <see cref="IChannelPoolHandler"/> that will be notified for the different pool actions.
 /// </param>
 /// <param name="healthChecker">
 /// The <see cref="IChannelHealthChecker"/> that will be used to check if a <see cref="IChannel"/> is still
 /// healthy when obtained from the <see cref="IChannelPool"/>.
 /// </param>
 /// <param name="action">
 /// The <see cref="AcquireTimeoutAction"/> to use or <c>null</c> if none should be used. In this case,
 /// <paramref name="acquireTimeout"/> must also be <c>null</c>.
 /// </param>
 /// <param name="acquireTimeout">
 /// A <see cref="TimeSpan"/> after which an pending acquire must complete, or the
 /// <see cref="AcquireTimeoutAction"/> takes place.
 /// </param>
 /// <param name="maxConnections">
 /// The number of maximal active connections. Once this is reached, new attempts to acquire an
 /// <see cref="IChannel"/> will be delayed until a connection is returned to the pool again.
 /// </param>
 /// <param name="maxPendingAcquires">
 /// The maximum number of pending acquires. Once this is exceeded, acquire attempts will be failed.
 /// </param>
 /// <param name="releaseHealthCheck">If <c>true</c>, will check channel health before offering it back.</param>
 public FixedChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, IChannelHealthChecker healthChecker, AcquireTimeoutAction action, TimeSpan acquireTimeout, int maxConnections, int maxPendingAcquires, bool releaseHealthCheck)
     : this(bootstrap, handler, healthChecker, action, acquireTimeout, maxConnections, maxPendingAcquires, releaseHealthCheck, true)
 {
 }
 /// <summary>
 /// Creates a new <see cref="SimpleChannelPool"/> instance.
 /// </summary>
 /// <param name="bootstrap">The <see cref="Bootstrapping.Bootstrap"/> that is used for connections.</param>
 /// <param name="handler">
 /// The <see cref="IChannelPoolHandler"/> that will be notified for the different pool actions.
 /// </param>
 /// <param name="healthChecker">
 /// The <see cref="IChannelHealthChecker"/> that will be used to check if a <see cref="IChannel"/> is still
 /// healthy when obtained from the <see cref="IChannelPool"/>.
 /// </param>
 /// <param name="releaseHealthCheck">
 /// If <c>true</c>, will check channel health before offering back. Otherwise, channel health is only checked
 /// at acquisition time.
 /// </param>
 public SimpleChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, IChannelHealthChecker healthChecker, bool releaseHealthCheck)
     : this(bootstrap, handler, healthChecker, releaseHealthCheck, true)
 {
 }
예제 #9
0
 static ChannelActiveHealthChecker()
 {
     Instance = new ChannelActiveHealthChecker();
 }