/// <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, (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 Start() { var reset = this.mre = new ManualResetEvent(false); // subscribe to the config url this.listener = this.GetPooledListener(); 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(); }
/// <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(); }
/// <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, (client, root) => ResolveBucketUri(client, root, name)); retval.Timeout = 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; }