コード例 #1
0
        /// <summary>
        /// Finds the <see cref="T:MemcachedNode"/> which is responsible for the specified item
        /// </summary>
        /// <param name="itemKey"></param>
        /// <returns></returns>
        private MemcachedNode LocateNode(string itemKey)
        {
            this.serverAccessLock.AcquireReaderLock(Timeout.Infinite);

            try
            {
                MemcachedNode node = this.NodeLocator.Locate(itemKey);
                if (node == null)
                {
                    return(null);
                }

                if (node.IsAlive)
                {
                    return(node);
                }

                this.MarkAsDead(node);

                return(this.LocateNode(itemKey));
            }
            finally
            {
                this.serverAccessLock.ReleaseLock();
            }
        }
コード例 #2
0
            internal InternalPoolImpl(
                MemcachedNode ownerNode,
                ISocketPoolConfiguration config,
                ILogger logger)
            {
                if (config.MinPoolSize < 0)
                {
                    throw new InvalidOperationException("minItems must be larger >= 0", null);
                }
                if (config.MaxPoolSize < config.MinPoolSize)
                {
                    throw new InvalidOperationException("maxItems must be larger than minItems", null);
                }
                if (config.QueueTimeout < TimeSpan.Zero)
                {
                    throw new InvalidOperationException("queueTimeout must be >= TimeSpan.Zero", null);
                }

                this.ownerNode    = ownerNode;
                this.isAlive      = true;
                _endPoint         = ownerNode.EndPoint;
                this.queueTimeout = config.QueueTimeout;

                this.minItems = config.MinPoolSize;
                this.maxItems = config.MaxPoolSize;

                _semaphore = new SemaphoreSlim(maxItems, maxItems);
                _freeItems = new InterlockedStack <PooledSocket>();

                _logger         = logger;
                _isDebugEnabled = _logger.IsEnabled(LogLevel.Debug);
            }
コード例 #3
0
            internal InternalPoolImpl(MemcachedNode ownerNode, ISocketPoolConfiguration config)
            {
                if (config.MinPoolSize < 0)
                {
                    throw new InvalidOperationException("minItems must be larger >= 0", null);
                }
                if (config.MaxPoolSize < config.MinPoolSize)
                {
                    throw new InvalidOperationException("maxItems must be larger than minItems", null);
                }
                if (config.QueueTimeout < TimeSpan.Zero)
                {
                    throw new InvalidOperationException("queueTimeout must be >= TimeSpan.Zero", null);
                }

                this.ownerNode    = ownerNode;
                this.isAlive      = true;
                this.endPoint     = ownerNode.EndPoint;
                this.queueTimeout = config.QueueTimeout;

                this.minItems = config.MinPoolSize;
                this.maxItems = config.MaxPoolSize;

                this.semaphore = new Semaphore(maxItems, maxItems);
                this.freeItems = new InterlockedStack <PooledSocket>();
            }
コード例 #4
0
            internal InternalPoolImpl(MemcachedNode ownerNode, ISocketPoolConfiguration config)
            {
                if (config.MinPoolSize < 0)
                {
                    throw new InvalidOperationException("Min pool size must be larger >= 0", null);
                }
                if (config.MaxPoolSize < config.MinPoolSize)
                {
                    throw new InvalidOperationException("Max pool size must be larger than min pool size", null);
                }
                if (config.QueueTimeout < TimeSpan.Zero)
                {
                    throw new InvalidOperationException("queueTimeout must be >= TimeSpan.Zero", null);
                }

                this._ownerNode    = ownerNode;
                this._endpoint     = ownerNode.EndPoint;
                this._queueTimeout = config.QueueTimeout;

                this._minItems = config.MinPoolSize;
                this._maxItems = config.MaxPoolSize;

                this._semaphore = new Semaphore(this._maxItems, this._maxItems);
                this._freeItems = new InterlockedStack <PooledSocket>();

                this._logger = Logger.CreateLogger <InternalPoolImpl>();
            }
コード例 #5
0
            /// <summary>
            /// Releases all resources allocated by this instance
            /// </summary>
            public void Dispose()
            {
                // this is not a graceful shutdown
                // if someone uses a pooled item then 99% that an exception will be thrown
                // somewhere. But since the dispose is mostly used when everyone else is finished
                // this should not kill any kittens
                if (!this.isDisposed)
                {
                    this.isAlive    = false;
                    this.isDisposed = true;

                    PooledSocket ps;

                    while (this.freeItems.TryPop(out ps))
                    {
                        try { ps.Destroy(); }
                        catch { }
                    }

                    this.ownerNode = null;
                    this.semaphore.Close();
                    this.semaphore = null;
                    this.freeItems = null;
                }
            }
コード例 #6
0
        private static List <uint> GenerateKeys(MemcachedNode node, int numberOfKeys)
        {
            const int KeyLength = 4;
            const int PartCount = 1;             // (ModifiedFNV.HashSize / 8) / KeyLength; // HashSize is in bits, uint is 4 byte long

            //if (partCount < 1)
            //    throw new ArgumentOutOfRangeException("The hash algorithm must provide at least 32 bits long hashes");

            List <uint> k = new List <uint>(PartCount * numberOfKeys);

            // every server is registered numberOfKeys times
            // using UInt32s generated from the different parts of the hash
            // i.e. hash is 64 bit:
            // 00 00 aa bb 00 00 cc dd
            // server will be stored with keys 0x0000aabb & 0x0000ccdd
            // (or a bit differently based on the little/big indianness of the host)
            string address = node.EndPoint.ToString();

            for (int i = 0; i < numberOfKeys; i++)
            {
                byte[] data = new FNV1a().ComputeHash(Encoding.ASCII.GetBytes(String.Concat(address, "-", i)));

                for (int h = 0; h < PartCount; h++)
                {
                    k.Add(BitConverter.ToUInt32(data, h * KeyLength));
                }
            }

            return(k);
        }
コード例 #7
0
        protected virtual IMemcachedNode CreateNode(EndPoint endpoint, Action <IMemcachedNode> onNodeFailed = null)
        {
            var node = new MemcachedNode(endpoint, this._configuration.SocketPool);

            if (onNodeFailed != null)
            {
                node.Failed += onNodeFailed;
            }
            return(node);
        }
コード例 #8
0
        public PooledSocket Acquire(string itemKey)
        {
            if (this.serverAccessLock == null)
            {
                throw new ObjectDisposedException("ServerPool");
            }

            MemcachedNode server = this.LocateNode(itemKey);

            if (server == null)
            {
                return(null);
            }

            return(server.Acquire());
        }
コード例 #9
0
        void IMemcachedNodeLocator.Initialize(IList<MemcachedNode> nodes)
        {
            if (this.isInitialized)
                throw new InvalidOperationException("Instance is already initialized.");

            // locking on this is rude but easy
            lock (this)
            {
                if (this.isInitialized)
                    throw new InvalidOperationException("Instance is already initialized.");

                if (nodes.Count > 0)
                    node = nodes[0];

                this.isInitialized = true;
            }
        }
コード例 #10
0
        /// <summary>
        /// Marks a node as dead (unusable)
        ///  - moves hte node to the  "dead list"
        ///  - recreates the locator based on the new list of still functioning servers
        /// </summary>
        /// <param name="node"></param>
        private void MarkAsDead(MemcachedNode node)
        {
            this.serverAccessLock.UpgradeToWriterLock(Timeout.Infinite);

            try
            {
                // server gained AoeREZ while AFK?
                if (!node.IsAlive)
                {
                    this.workingServers.Remove(node);
                    this.deadServers.Add(node);

                    this.RebuildIndexes();
                }
            }
            finally
            {
                this.serverAccessLock.ReleaseLock();
            }
        }
コード例 #11
0
        public IDictionary <MemcachedNode, IList <string> > SplitKeys(IEnumerable <string> keys)
        {
            Dictionary <MemcachedNode, IList <string> > keysByNode = new Dictionary <MemcachedNode, IList <string> >(MemcachedNode.Comparer.Instance);

            foreach (string key in keys)
            {
                MemcachedNode node = LocateNode(key);

                IList <string> nodeKeys;
                if (!keysByNode.TryGetValue(node, out nodeKeys))
                {
                    nodeKeys = new List <string>();
                    keysByNode.Add(node, nodeKeys);
                }

                nodeKeys.Add(key);
            }

            return(keysByNode);
        }
コード例 #12
0
        void IMemcachedNodeLocator.Initialize(IList <MemcachedNode> nodes)
        {
            if (this.isInitialized)
            {
                throw new InvalidOperationException("Instance is already initialized.");
            }

            // locking on this is rude but easy
            lock (this)
            {
                if (this.isInitialized)
                {
                    throw new InvalidOperationException("Instance is already initialized.");
                }

                if (nodes.Count > 0)
                {
                    node = nodes[0];
                }

                this.isInitialized = true;
            }
        }
コード例 #13
0
            void Dispose(bool disposing)
            {
                if (disposing && !isDisposed)
                {
                    GC.SuppressFinalize(this);
                }
                if (!isDisposed)
                {
                    new Timer((s) =>
                    {
                        if (!this.isDisposed)
                        {
                            log.Debug("Disposing InternalPoolImpl");

                            IPooledSocket ps;
                            while (this.freeItems.TryPop(out ps))
                            {
                                try
                                {
                                    ps.Dispose();
                                }
                                catch (Exception e)
                                {
                                    log.Error(e);
                                }
                            }

                            this.ownerNode = null;
                            this.semaphore.Close();
                            this.semaphore  = null;
                            this.freeItems  = null;
                            this.isAlive    = false;
                            this.isDisposed = true;
                        }
                    }, null, 1000, Timeout.Infinite);
                }
            }
コード例 #14
0
 protected abstract void WriteNodeInfo(MemcachedNode node);
コード例 #15
0
 protected override void WriteNodeInfo(MemcachedNode node)
 {
     WriteVerbose(Key + " - decrementing on - " + node.EndPoint.ToString());
 }
コード例 #16
0
 protected override void WriteNodeInfo(MemcachedNode node)
 {
     WriteVerbose(Key + " - retrieving from - " + node.EndPoint.ToString());
 }
コード例 #17
0
ファイル: Publisher.cs プロジェクト: brianhartsock/MemPowered
 public static void Publish(MemcachedNode node)
 {
     registrants.ForEach(a => a.Invoke(node));
 }
コード例 #18
0
        /// <summary>
        /// Marks a node as dead (unusable)
        ///  - moves hte node to the  "dead list"
        ///  - recreates the locator based on the new list of still functioning servers
        /// </summary>
        /// <param name="node"></param>
        private void MarkAsDead(MemcachedNode node)
        {
            this.serverAccessLock.UpgradeToWriterLock(Timeout.Infinite);

            try
            {
                // server gained AoeREZ while AFK?
                if (!node.IsAlive)
                {
                    this.workingServers.Remove(node);
                    this.deadServers.Add(node);

                    this.RebuildIndexes();
                }
            }
            finally
            {
                this.serverAccessLock.ReleaseLock();
            }
        }
 public InstancePerformanceCounters(MemcachedNode node)
     : this(node.EndPoint.ToString())
 {
 }
コード例 #20
0
        private static List<uint> GenerateKeys(MemcachedNode node, int numberOfKeys)
        {
            const int KeyLength = 4;
            const int PartCount = 1; // (ModifiedFNV.HashSize / 8) / KeyLength; // HashSize is in bits, uint is 4 byte long

            //if (partCount < 1)
            //    throw new ArgumentOutOfRangeException("The hash algorithm must provide at least 32 bits long hashes");

            List<uint> k = new List<uint>(PartCount * numberOfKeys);

            // every server is registered numberOfKeys times
            // using UInt32s generated from the different parts of the hash
            // i.e. hash is 64 bit:
            // 00 00 aa bb 00 00 cc dd
            // server will be stored with keys 0x0000aabb & 0x0000ccdd
            // (or a bit differently based on the little/big indianness of the host)
            string address = node.EndPoint.ToString();

            for (int i = 0; i < numberOfKeys; i++)
            {
                byte[] data = new FNV1a().ComputeHash(Encoding.ASCII.GetBytes(String.Concat(address, "-", i)));

                for (int h = 0; h < PartCount; h++)
                {
                    k.Add(BitConverter.ToUInt32(data, h * KeyLength));
                }
            }

            return k;
        }