Exemplo n.º 1
0
        /// <summary>
        /// Calls OnCompleted on all Subscribers, unsubscribes them,
        ///     and stops receiving messages on the queue.
        /// </summary>
        /// <exception cref="System.InvalidOperationException"></exception>
        /// <returns>A result containing any Exceptions from removing Subscribers</returns>
        public StopReceivingResult StopReceiving()
        {
            if (_observers.IsNone || _workers.IsNone || _tokenSource.IsNone)
            {
                throw new InvalidOperationException($"{nameof(BrokerClient)} has not started receiving");
            }

            var tokenSource = _tokenSource | CancellationTokenSource.CreateLinkedTokenSource(CancellationToken.None);
            var workers     = _workers | new ConcurrentBag <Task>();
            var observers   = _observers | new ConcurrentBag <IBrokerObserver>();

            return(new StopReceivingResult(Try(() => tokenSource.Cancel()).Try())
                   .Append(Try(() => Task.WaitAll(workers.ToArray(), tokenSource.Token)).Try())
                   .Append(Try(() => _logger.Debug(message: "Receiver stopped")).Try())
                   .Append(Try(() => tokenSource.Dispose()).Try())
                   .Append(
                       _logger.Debug(observers, "Calling Observers OnCompleted").Aggregate(
                           new StopReceivingResult(),
                           (prev, next) =>
                           prev.Append(Try(() => next.OnCompleted()).Try())))
                   .Append(
                       new StopReceivingResult(Try(() =>
            {
                IBrokerObserver removing;
                while (observers.TryTake(out removing))
                {
                }
                ;
                _logger.Debug("All Observers Removed");
            }).Try())));
        }
Exemplo n.º 2
0
 /// <summary>
 /// Adds error handling to IObserver.OnError
 /// </summary>
 /// <param name="self"></param>
 /// <param name="exception"></param>
 /// <param name="message"></param>
 /// <param name="logger"></param>
 /// <returns></returns>
 public static Unit SendError(this IBrokerObserver self, Exception exception, Maybe <BrokerMessage> message, Maybe <Log> logger) =>
 Try(() => self.OnError(exception, message))
 .Match(_ => _,
        e => logger.Error <Unit>(
            new AggregateException(
                exception,
                logger.Debug(e, $"{nameof(self.OnNext)} failed. Calling {nameof(self.OnError)}")).GetExceptionChainMessagesWithSql()));
Exemplo n.º 3
0
        /// <summary>
        /// Adds a new observer to receive future queue messages
        /// </summary>
        /// <remarks>Be aware that <see cref="IObserver{T}.OnNext(T)"/>, <see cref="IObserver{T}.OnError(Exception)"/>,
        /// and <see cref="IObserver{T}.OnCompleted()"/> are called asynchronously;
        /// so appropriate state sharing precautions should be taken to avoid race conditions.</remarks>
        /// <param name="observer">New addition that needs to implement <see cref="IBrokerObserver"/></param>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.InvalidOperationException">When <paramref name="observer"/> is not an <see cref="IBrokerObserver"/></exception>
        /// <returns>A subscription that can be unsubscribed from by calling Dispose</returns>
        public IDisposable Subscribe(IBrokerObserver observer)
        {
            if (!_observers.Contains(observer.AssertValue()))
            {
                _observers.Add(observer);

                _logger.Debug($"Added {observer}");
            }

            return(new Subscription(_observers, observer, _logger));
        }
Exemplo n.º 4
0
        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing && _observer != null && _observers != null && _observers.Contains(_observer))
                {
                    IBrokerObserver removing;
                    if (_observers.TryTake(out removing))
                    {
                        _logger.Debug($"Removed Observer: {ToString()}");
                    }
                    else
                    {
                        _logger.Error($"Failed to remove Observer: {ToString()}");
                    }
                }

                disposedValue = true;
            }
        }
Exemplo n.º 5
0
 /// <summary>
 /// Adds error handling to IObserver.OnNext
 /// </summary>
 /// <param name="self"></param>
 /// <param name="next"></param>
 /// <param name="logger"></param>
 /// <returns></returns>
 public static Unit SendNext(this IBrokerObserver self, BrokerMessage next, Maybe <Log> logger) =>
 Try(() => self.OnNext(next)).Match(
     _ => _,
     e => self.SendError(logger.Debug(e, $"{nameof(self.OnNext)} failed. Calling {nameof(self.OnError)}"), next, logger));