Beispiel #1
0
        /// <summary>
        /// Handles the subscription of a new TopicPartition to this fetcher.
        /// Keeps track of the subscribed partitions in order to not fetch messages if the FlowControlState is Closed.
        /// </summary>
        /// <param name="topicPartition"></param>
        /// <returns></returns>
        public IDisposable Subscribe(TopicPartition topicPartition)
        {
            _topicPartitions.Add(topicPartition);
            EtwTrace.Log.FetcherPartitionSubscribed(_id, topicPartition.PartitionId);

            // cleanup
            var topicPartitionCleanup = Disposable.Create(() => _topicPartitions.Remove(topicPartition));
            var receivedMessagesSubscriptionCleanup = ReceivedMessages.
                                                      Where(rm => rm.Topic == topicPartition.Topic && rm.Partition == topicPartition.PartitionId)
                                                      .Subscribe(topicPartition);
            var flowControlCleanup = topicPartition.FlowControl.
                                     // we need to wake up from waiting loop any time flow control hits low watermark and becomes enabled
                                     Where(enabled => enabled).
                                     Subscribe(_ => _wakeupSignal.OnNext(true));

            var cleanup = new CompositeDisposable
            {
                topicPartitionCleanup,
                receivedMessagesSubscriptionCleanup,
                flowControlCleanup
            };

            if (_log.IsDebugEnabled)
            {
                cleanup.Add(Disposable.Create(() => _log.Debug("Fetcher #{0} {1} topicPartition is unsubscribing", _id, topicPartition)));
            }

            _log.Debug("Fetcher #{0} added {1}", _id, topicPartition);

            return(cleanup);
        }
Beispiel #2
0
        public IActionResult Index(EventHubModel model)
        {
            // Apply input history from cookie
            var cu = ControllerUtils.From(this);

            cu.PersistInput("ConnectionString", model, EventHubModel.Default.ConnectionString);
            cu.PersistInput("EventHubName", model, EventHubModel.Default.EventHubName);
            cu.PersistInput("ConsumerGroupName", model, EventHubModel.Default.ConsumerGroupName);
            cu.PersistInput("StorageConnectionString", model, EventHubModel.Default.StorageConnectionString);
            cu.PersistInput("StorageContainerName", model, EventHubModel.Default.StorageContainerName);

            var receiveTimeout = model.ListeningTime - TimeSpan.FromMilliseconds(200 * 2);

            if (model.ConsumerGroupName == EventHubModel.Default.ConsumerGroupName)
            {
                model.ConsumerGroupName = PartitionReceiver.DefaultConsumerGroupName;
            }

            try
            {
                var cs = new EventHubsConnectionStringBuilder(model.ConnectionString)
                {
                    EntityPath = model.EventHubName,
                };
                var ec = EventHubClient.CreateFromConnectionString(cs.ToString()); // WARNING : Max # of TCP socket because of each instance created by Http Request


                if (model.ReceiveRequested)
                {
                    var eph = new EventProcessorHost(
                        model.EventHubName,
                        model.ConsumerGroupName,
                        model.ConnectionString,
                        model.StorageConnectionString,
                        model.StorageContainerName);

                    eph.RegisterEventProcessorFactoryAsync(this, new EventProcessorOptions
                    {
                        InvokeProcessorAfterReceiveTimeout = true,
                        ReceiveTimeout = receiveTimeout,    // It's necessary to set long time here. (1.6sec was not enough at 2020.7.30)
                    }
                                                           ).ConfigureAwait(false).GetAwaiter().GetResult();

                    Task.Delay(receiveTimeout + TimeSpan.FromMilliseconds(200)).ConfigureAwait(false).GetAwaiter().GetResult();    // wait message received

                    eph.UnregisterEventProcessorAsync().ConfigureAwait(false).GetAwaiter().GetResult();

                    model.ActionMessage = "";
                    var err = ErrorMessages.ToString();
                    if (!string.IsNullOrEmpty(err))
                    {
                        model.ActionMessage = $"{err}{Environment.NewLine}{Environment.NewLine}";
                    }
                    model.ActionMessage += $"Received {ReceivedMessages.Count} messages.{Environment.NewLine}{Environment.NewLine}{string.Join(Environment.NewLine, ReceivedMessages.Where(a => a != null))}";
                    if (ReceivedMessages.Count > 5)
                    {
                        model.ActionMessage += $"{Environment.NewLine}...more";
                    }

                    Task.Delay(TimeSpan.FromMilliseconds(200)).ConfigureAwait(false).GetAwaiter().GetResult();    // wait message received
                }
                else
                if (!model.SkipSend)
                {
                    ec.SendAsync(new EventData(Encoding.UTF8.GetBytes(model.Message))).ConfigureAwait(false).GetAwaiter().GetResult();
                    model.ActionMessage = $"OK : Sent '{model.Message}' to {model.EventHubName}";
                }

                // Collect Partition Information
                var isNetError  = false;
                var runtimeInfo = ec.GetRuntimeInformationAsync().ConfigureAwait(false).GetAwaiter().GetResult();
                foreach (var pid in runtimeInfo.PartitionIds)
                {
                    if (isNetError == false)
                    {
                        try
                        {
                            var pi = ec.GetPartitionRuntimeInformationAsync(pid).ConfigureAwait(false).GetAwaiter().GetResult();
                            if (model.PartitionInfo == null)
                            {
                                model.PartitionInfo = new Dictionary <string, EventHubPartitionRuntimeInformation>();
                            }
                            model.PartitionInfo[pid] = pi;
                        }
                        catch (SocketException ex)
                        {
                            throw ex;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                for (var exx = ex; exx != null; exx = ex.InnerException)
                {
                    model.ActionMessage = $"ERROR : {exx.Message}{Environment.NewLine}";
                }
            }

            model.ReceiveRequested = false;
            model.SkipSend         = false;

            return(View(model));
        }