/// <inheritdoc /> public void SubscribeToChannels(TimeSpan timeout, IEnumerable <string> channelsToSubscribe) { if (channelsToSubscribe == null) { throw new ArgumentNullException("channelsToSubscribe"); } Trace.WriteLine("ENTER: Subscribing to channels {0} ...".FormatInvariant(channelsToSubscribe.ToString(","))); if (timeout <= TimeSpan.Zero) { throw new ArgumentOutOfRangeException("timeout", timeout, "Value must be positive."); } if (this.disposeState != DisposeState.None) { throw new ObjectDisposedException(this.debugName); } List <string> channelsToSubscribe1 = channelsToSubscribe .Except(this.channels) .Distinct() .ToList(); if (channelsToSubscribe1.Count == 0) { Trace.WriteLine("EXIT: No channels to subscribe."); return; } if (this.channels.Count == 0) { channelsToSubscribe1.Add(ServiceStackSubscription.UnsubscribeChannel); } SubscribeOperationState subscribeOperation = new SubscribeOperationState(SubscribeOperation.Subscribe, channelsToSubscribe1); this.subscribeOperations.Add(subscribeOperation); ThreadPool.QueueUserWorkItem(state => { try { this.subscription.SubscribeToChannels(channelsToSubscribe1.ToArray()); } catch (Exception ex) { if (ex.IsCritical()) { throw; } Trace.TraceWarning(ex.ToString()); } }); if (timeout == TimeSpan.MaxValue) { subscribeOperation.Blocker.Wait(); } else if (!subscribeOperation.Blocker.Wait(timeout)) { throw new TimeoutException("Subscribe to channels '{0}' timed out after {1}.".FormatInvariant(channelsToSubscribe.ToString(","), timeout)); } Trace.WriteLine("EXIT: Subscribed to channels {0}.".FormatInvariant(channelsToSubscribe.ToString(","))); }
/// <inheritdoc /> public bool UnsubscribeFromChannels(TimeSpan timeout, IEnumerable <string> channelsToUnsubscribe) { if (channelsToUnsubscribe == null) { throw new ArgumentNullException("channelsToUnsubscribe"); } string channelsDebugString = channelsToUnsubscribe.ToString(","); Trace.WriteLine("ENTER: Unsubscribing from channels {0} ...".FormatInvariant(channelsDebugString)); if (timeout <= TimeSpan.Zero) { throw new ArgumentOutOfRangeException("timeout", timeout, "Value must be positive."); } if (this.disposeState != DisposeState.None) { Trace.Flush(); throw new ObjectDisposedException(this.debugName); } List <string> channelsToUnsubscribe1 = channelsToUnsubscribe.Where(c => this.channels.Contains(c)).Distinct().ToList(); if (channelsToUnsubscribe1.Count == 0) { Trace.WriteLine("EXIT: No channels to unsubscribe from."); return(true); } if (channelsToUnsubscribe1.Count == this.channels.Count) { channelsToUnsubscribe1.Add(UnsubscribeChannel); } SubscribeOperationState subscribeOperation = new SubscribeOperationState(SubscribeOperation.Unsubscribe, channelsToUnsubscribe); this.subscribeOperations.Add(subscribeOperation); using (RedisClient client2 = new RedisClient(this.client.Host)) { client2.PublishMessage(ServiceStackSubscription.UnsubscribeChannel, RedisConverter.ToString(channelsToUnsubscribe)); } if (timeout == TimeSpan.MaxValue) { subscribeOperation.Blocker.Wait(); Trace.WriteLine("EXIT: Unsubscribed from channels {0}.".FormatInvariant(channelsDebugString)); return(true); } if (subscribeOperation.Blocker.Wait(timeout)) { Trace.WriteLine("EXIT: Unsubscribed from channels {0}.".FormatInvariant(channelsDebugString)); return(true); } else { Trace.WriteLine("EXIT: Failed to unsubscribe from channels {0} within the specified timeout {1}.".FormatInvariant(channelsDebugString, timeout)); return(false); } }