Beispiel #1
0
        internal static ConnectorPool GetOrAdd(string key, ConnectorPool pool)
        {
            lock (_lock)
            {
                if (TryGetValue(key, out var result))
                {
                    return(result);
                }

                // May need to grow the array.
                if (_nextSlot == _pools.Length)
                {
                    var newPools = new (string, ConnectorPool)[_pools.Length * 2];
Beispiel #2
0
        internal static bool TryGetValue(string key, out ConnectorPool pool)
        {
            // Note that pools never get removed. _pools is strictly append-only.
            var nextSlot = _nextSlot;
            var pools    = _pools;
            var sw       = new SpinWait();

            // First scan the pools and do reference equality on the connection strings
            for (var i = 0; i < nextSlot; i++)
            {
                var cp = pools[i];
                if (ReferenceEquals(cp.Key, key))
                {
                    // It's possible that this pool entry is currently being written: the connection string
                    // component has already been writte, but the pool component is just about to be. So we
                    // loop on the pool until it's non-null
                    while (Volatile.Read(ref cp.Pool) == null)
                    {
                        sw.SpinOnce();
                    }
                    pool = cp.Pool;
                    return(true);
                }
            }

            // Next try value comparison on the strings
            for (var i = 0; i < nextSlot; i++)
            {
                var cp = pools[i];
                if (cp.Key == key)
                {
                    // See comment above
                    while (Volatile.Read(ref cp.Pool) == null)
                    {
                        sw.SpinOnce();
                    }
                    pool = cp.Pool;
                    return(true);
                }
            }

            pool = null;
            return(false);
        }
Beispiel #3
0
        public MultiHostConnectorPool(NpgsqlConnectionStringBuilder settings, string connString) : base(settings, connString)
        {
            var hosts = settings.Host !.Split(',');

            _pools = new ConnectorPool[hosts.Length];
            for (var i = 0; i < hosts.Length; i++)
            {
                var host          = hosts[i].Trim();
                var port          = settings.Port;
                var portSeparator = host.IndexOf(':');
                if (portSeparator != -1)
                {
                    port = int.Parse(host.Substring(portSeparator + 1));
                    host = host.Substring(0, portSeparator);
                }
                var poolSettings = settings.Clone();
                poolSettings.Host = host;
                poolSettings.Port = port;
                _pools[i]         = new ConnectorPool(poolSettings, poolSettings.ConnectionString, this);
            }
        }