예제 #1
0
        /// <summary>
        /// <see cref="UnarySequentialDispatcherRemoteNode{TInput}"/>
        /// </summary>
        /// <param name="persistentCache">Persistent cache to avoid dropped data on system crash</param>
        /// <param name="progress">Progress of the current bulk</param>
        /// <param name="host"><see cref="Host"/></param>
        /// <param name="cts"><see cref="CancellationTokenSource"/></param>
        /// <param name="circuitBreakerOptions"><see cref="CircuitBreakerOptions"/></param>
        /// <param name="clusterOptions"><see cref="ClusterOptions"/></param>
        /// <param name="logger"><see cref="ILogger"/></param>
        public UnarySequentialDispatcherRemoteNode(
            IAppCache persistentCache,
            IProgress <double> progress,
            Host host,
            CancellationTokenSource cts,
            CircuitBreakerOptions circuitBreakerOptions,
            ClusterOptions clusterOptions,
            ILogger logger) : base(
                Policy.Handle <Exception>()
                .AdvancedCircuitBreakerAsync(circuitBreakerOptions.CircuitBreakerFailureThreshold,
                                             circuitBreakerOptions.CircuitBreakerSamplingDuration,
                                             circuitBreakerOptions.CircuitBreakerMinimumThroughput,
                                             circuitBreakerOptions.CircuitBreakerDurationOfBreak,
                                             onBreak: (ex, timespan, context) =>
        {
            logger.LogError(
                $"Batch processor breaker: Breaking the circuit for {timespan.TotalMilliseconds}ms due to {ex.Message}.");
        },
                                             onReset: context =>
        {
            logger.LogInformation(
                "Batch processor breaker: Succeeded, closed the circuit.");
        },
                                             onHalfOpen: () =>
        {
            logger.LogWarning(
                "Batch processor breaker: Half-open, next call is a trial.");
        }), clusterOptions, progress, cts, logger)
        {
            _logger         = logger;
            _clusterOptions = clusterOptions;

            ISubject <PersistentItem <TInput> > dispatcherSubject = new Subject <PersistentItem <TInput> >();
            _synchronizedDispatcherSubject             = Subject.Synchronize(dispatcherSubject);
            _synchronizedDispatcherSubjectSubscription = _synchronizedDispatcherSubject
                                                         .ObserveOn(new EventLoopScheduler(ts => new Thread(ts)))
                                                         .Select(item =>
            {
                return(Observable.FromAsync(() => persistentCache.AddItemAsync(item.Entity,
                                                                               item.CancellationTokenSource.Token)));
            })
                                                         .Merge()
                                                         .Subscribe();

            var channel = new Channel(host.MachineName, host.Port,
                                      ChannelCredentials.Insecure);
            _remoteContract = MagicOnionClient.Create <IRemoteContract <TInput> >(channel);
            IRemoteNodeSubject nodeReceiver = new NodeReceiver(_logger);
            _remoteNodeHealthSubscription =
                nodeReceiver.RemoteNodeHealthSubject.Subscribe(remoteNodeHealth =>
            {
                NodeMetrics.RemoteNodeHealth = remoteNodeHealth;
            });
            _nodeHub = StreamingHubClient.Connect <INodeHub, INodeReceiver>(channel, (INodeReceiver)nodeReceiver);

            NodeMetrics = new NodeMetrics(Guid.NewGuid());
        }
예제 #2
0
        /// <summary>
        /// <see cref="UnarySequentialDispatcherLocalNode{TInput}"/>
        /// </summary>
        /// <param name="persistentCache">Persistent cache to avoid dropped data on system crash</param>
        /// <param name="process">The <see cref="Task"/> to be applied to an item</param>
        /// <param name="progress">Progress of the current bulk</param>
        /// <param name="cts"><see cref="CancellationTokenSource"/></param>
        /// <param name="circuitBreakerOptions"><see cref="CircuitBreakerOptions"/></param>
        /// <param name="clusterOptions"><see cref="ClusterOptions"/></param>
        /// <param name="logger"><see cref="ILogger"/></param>
        public UnarySequentialDispatcherLocalNode(
            IAppCache persistentCache,
            Func <TInput, NodeMetrics, CancellationToken, Task> process,
            IProgress <double> progress,
            CancellationTokenSource cts,
            CircuitBreakerOptions circuitBreakerOptions,
            ClusterOptions clusterOptions,
            ILogger logger) : base(
                Policy.Handle <Exception>()
                .AdvancedCircuitBreakerAsync(circuitBreakerOptions.CircuitBreakerFailureThreshold,
                                             circuitBreakerOptions.CircuitBreakerSamplingDuration,
                                             circuitBreakerOptions.CircuitBreakerMinimumThroughput,
                                             circuitBreakerOptions.CircuitBreakerDurationOfBreak,
                                             onBreak: (ex, timespan, context) =>
        {
            logger.LogError(
                $"Batch processor breaker: Breaking the circuit for {timespan.TotalMilliseconds}ms due to {ex.Message}.");
        },
                                             onReset: context =>
        {
            logger.LogInformation(
                "Batch processor breaker: Succeeded, closed the circuit.");
        },
                                             onHalfOpen: () =>
        {
            logger.LogWarning(
                "Batch processor breaker: Half-open, next call is a trial.");
        }), clusterOptions, progress, cts, logger)
        {
            _logger         = logger;
            _process        = process;
            _clusterOptions = clusterOptions;

            ISubject <PersistentItem <TInput> > dispatcherSubject = new Subject <PersistentItem <TInput> >();
            _synchronizedDispatcherSubject             = Subject.Synchronize(dispatcherSubject);
            _synchronizedDispatcherSubjectSubscription = _synchronizedDispatcherSubject
                                                         .ObserveOn(new EventLoopScheduler(ts => new Thread(ts)))
                                                         .Select(item =>
            {
                return(Observable.FromAsync(() => persistentCache.AddItemAsync(item.Entity,
                                                                               item.CancellationTokenSource.Token)));
            })
                                                         .Merge()
                                                         .Subscribe();

            NodeMetrics = new NodeMetrics(Guid.NewGuid());
        }