Esempio n. 1
0
        /// <summary>
        /// Returns a MessageStreamListener instance based on this instance's configuration (timeout, bucket name etc.)
        ///
        /// When multiple listeners are requested with the exact same parameters (usually when multiple clients are instantiated from the same configuration),
        /// the same listener will be returned each time.
        /// </summary>
        /// <returns></returns>
        private MessageStreamListener GetPooledListener()
        {
            // create a unique key based on the parameters
            // to find out if we already have a listener attached to this pool
            var hcc = new HashCodeCombiner();

            hcc.Add(this.Timeout);
            hcc.Add(this.DeadTimeout);
            hcc.Add(this.RetryCount);
            hcc.Add(this.RetryTimeout.GetHashCode());
            hcc.Add(this.bucketName.GetHashCode());

            if (credential != null)
            {
                hcc.Add((this.credential.UserName ?? String.Empty).GetHashCode());
                hcc.Add((this.credential.Password ?? String.Empty).GetHashCode());
                hcc.Add((this.credential.Domain ?? String.Empty).GetHashCode());
            }

            for (var i = 0; i < this.poolUrls.Length; i++)
            {
                hcc.Add(this.poolUrls[i].GetHashCode());
            }

            var hash = hcc.CurrentHash;

            MessageStreamListener retval;

            lock (ListenerSync)
                if (listeners.TryGetValue(hash, out retval))
                {
                    listenerRefs[retval].RefCount++;
                    retval.Subscribe(this.HandleMessage);
                }
                else
                {
                    var name = this.bucketName;

                    // create a new listener for the pool urls
                    retval = new MessageStreamListener(poolUrls, heartbeatUri, heartbeatInterval, isHeartbeatEnabled,
                                                       (client, root) => ResolveBucketUri(client, root, name));

                    retval.ConnectionTimeout = this.Timeout;
                    retval.DeadTimeout       = this.DeadTimeout;
                    retval.Credentials       = this.credential;
                    retval.RetryCount        = this.RetryCount;
                    retval.RetryTimeout      = this.RetryTimeout;

                    retval.Subscribe(this.HandleMessage);

                    listeners[hash]      = retval;
                    listenerRefs[retval] = new ListenerInfo {
                        RefCount = 1, HashKey = hash
                    };

                    retval.Start();
                }

            return(retval);
        }
Esempio n. 2
0
        private void HandleMessage(string message, MessageStreamListener listener)
        {
            // everything failed
            if (String.IsNullOrEmpty(message))
            {
                this.lastHash = null;
                this.RaiseConfigChanged(null);
                return;
            }

            // deserialize the buckets
            var jss = new JavaScriptSerializer();

            jss.RegisterConverters(KnownConverters);

            var config = jss.Deserialize <ClusterConfig>(message);

            // check if the config is the same as the previous
            // we cannot compare the messages because they have more information than we deserialize from them
            var configHash = config.GetHashCode();

            if (lastHash != configHash)
            {
                lastHash = configHash;
                this.RaiseConfigChanged(config);
                listener.UpdateNodes(config);
            }
            else if (log.IsDebugEnabled)
            {
                log.Debug("Last message was the same as current, ignoring.");
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Starts listening for configuration data. This method blocks until the initial configuration is received. (Or until all pool urls fail.)
        /// </summary>
        public void Start()
        {
            var reset = this.mre = new ManualResetEvent(false);

            // subscribe to the config url
            this.listener = this.GetPooledListener();

            // this will be signaled by the config changed event handler
            reset.WaitOne();

            // set to null, then dispose, so RaiseConfigChanged will not
            // fail at Set when the config changes while we're cleaning up here
            this.mre = null;
            ((IDisposable)reset).Dispose();
        }
Esempio n. 4
0
        /// <summary>
        /// Unsubscribes from a pooled listener, and destroys it if no additional subscribers are present.
        /// </summary>
        /// <param name="listener"></param>
        private void ReleaseListener(MessageStreamListener listener)
        {
            lock (ListenerSync)
            {
                listener.Unsubscribe(this.HandleMessage);

                var info = listenerRefs[listener];
                if (info.RefCount == 1)
                {
                    listenerRefs.Remove(listener);
                    listeners.Remove(info.HashKey);

                    try { using (listener) listener.Stop(); }
                    catch (Exception e) { log.Error(e); }
                }
                else
                {
                    info.RefCount--;
                }
            }
        }
        /// <summary>
        /// Unsubscibes from a pooled listener, and destrpys it if no additionals subscribers are present.
        /// </summary>
        /// <param name="listener"></param>
        private void ReleaseListener(MessageStreamListener listener)
        {
            lock (ListenerSync)
            {
                listener.Unsubscribe(this.HandleMessage);

                var info = listenerRefs[listener];
                if (info.RefCount == 1)
                {
                    listenerRefs.Remove(listener);
                    listeners.Remove(info.HashKey);

                    try { using (listener) listener.Stop(); }
                    catch { }
                }
                else
                {
                    info.RefCount--;
                }
            }
        }
        /// <summary>
        /// Returns a MessageStreamListener instance based on this instance's configuratino (timeout, bucket name etc.)
        /// 
        /// When multiple listeners are requested with the exact same parameters (usually when multiple clients are instantiated from the same configuration),
        /// the same listener will be returned each time.
        /// </summary>
        /// <returns></returns>
        private MessageStreamListener GetPooledListener()
        {
            // create a unique key based on the parameters
            // to find out if we already have a listener attached to this pool
            var hcc = new HashCodeCombiner();

            hcc.Add(this.Timeout);
            hcc.Add(this.DeadTimeout);
            hcc.Add(this.RetryCount);
            hcc.Add(this.RetryTimeout.GetHashCode());
            hcc.Add(this.bucketName.GetHashCode());

            if (credential != null)
            {
                hcc.Add((this.credential.UserName ?? String.Empty).GetHashCode());
                hcc.Add((this.credential.Password ?? String.Empty).GetHashCode());
                hcc.Add((this.credential.Domain ?? String.Empty).GetHashCode());
            }

            for (var i = 0; i < this.poolUrls.Length; i++)
                hcc.Add(this.poolUrls[i].GetHashCode());

            var hash = hcc.CurrentHash;

            MessageStreamListener retval;

            lock (ListenerSync)
                if (listeners.TryGetValue(hash, out retval))
                {
                    listenerRefs[retval].RefCount++;
                    retval.Subscribe(this.HandleMessage);
                }
                else
                {
                    var name = this.bucketName;

                    // create a new listener for the pool urls
                    retval = new MessageStreamListener(poolUrls, heartbeatUri, heartbeatInterval, isHeartbeatEnabled,
                                                (client, root) => ResolveBucketUri(client, root, name));

                    retval.ConnectionTimeout = this.Timeout;
                    retval.DeadTimeout = this.DeadTimeout;
                    retval.Credentials = this.credential;
                    retval.RetryCount = this.RetryCount;
                    retval.RetryTimeout = this.RetryTimeout;

                    retval.Subscribe(this.HandleMessage);

                    listeners[hash] = retval;
                    listenerRefs[retval] = new ListenerInfo { RefCount = 1, HashKey = hash };

                    retval.Start();
                }

            return retval;
        }
 public void Stop()
 {
     this.ReleaseListener(this.listener);
     this.listener = null;
 }
        /// <summary>
        /// Starts listening for configuration data. This method blocks until the initial configuration is received. (Or until all pool urls fail.)
        /// </summary>
        public void Start()
        {
            var reset = this.mre = new ManualResetEvent(false);

            // subscribe to the config url
            this.listener = this.GetPooledListener();

            // this will be signaled by the config changed event handler
            reset.WaitOne();

            // set to null, then dispose, so RaiseConfigChanged will not
            // fail at Set when the config changes while we're cleaning up here
            this.mre = null;
            ((IDisposable)reset).Dispose();
        }
Esempio n. 9
0
 public void Stop()
 {
     this.ReleaseListener(this.listener);
     this.listener = null;
 }
        private void HandleMessage(string message, MessageStreamListener listener)
        {
            // everything failed
            if (String.IsNullOrEmpty(message))
            {
                this.lastHash = null;
                this.RaiseConfigChanged(null);
                return;
            }

            // deserialize the buckets
            var jss = new JavaScriptSerializer();
            jss.RegisterConverters(KnownConverters);

            var config = jss.Deserialize<ClusterConfig>(message);

            // check if the config is the same as the previous
            // we cannot compare the messages because they have more information than we deserialize from them
            var configHash = config.GetHashCode();

            if (lastHash != configHash)
            {
                lastHash = configHash;
                this.RaiseConfigChanged(config);
                listener.UpdateNodes(config);
            }
            else if (log.IsDebugEnabled)
                log.Debug("Last message was the same as current, ignoring.");
        }