Ejemplo n.º 1
0
        public async Task Receive()
        {
            try
            {
                using (ITransaction tx = stateManager.CreateTransaction())
                {
                    ConditionalValue <string> offsetResult = await offsetDictionary.TryGetValueAsync(tx, "offset", LockMode.Default);

                    ConditionalValue <long> epochResult = await epochDictionary.TryGetValueAsync(tx, "epoch", LockMode.Update);

                    long newEpoch = epochResult.HasValue ? epochResult.Value + 1 : 0;
                    await epochDictionary.SetAsync(tx, "epoch", newEpoch);

                    PartitionReceiver partitionReceiver;

                    if (offsetResult.HasValue)
                    {
                        partitionReceiver = eventHubClient.CreateEpochReceiver(PartitionReceiver.DefaultConsumerGroupName,
                                                                               "3",    //Convert.ToString(this.servicePartitionKey),
                                                                               offsetResult.Value,
                                                                               newEpoch);
                    }
                    else
                    {
                        partitionReceiver = eventHubClient.CreateEpochReceiver(PartitionReceiver.DefaultConsumerGroupName,
                                                                               Convert.ToString(this.servicePartitionKey),
                                                                               "-1",
                                                                               newEpoch);
                    }

                    ServiceEventSource.Current.ServiceMessage(this.serviceContext,
                                                              $"Partition Id: {servicePartitionKey}; offset: {offsetResult.Value}; Epoch: {newEpoch}");
                    var ehEvents = await partitionReceiver.ReceiveAsync(1);
                    await GenerateActors(ehEvents, tx);

                    await tx.CommitAsync();
                }
            }
            catch (EventHubsException ex)
            {
                ServiceEventSource.Current.ServiceMessage(this.serviceContext, ex.Message);
            }
            catch (Exception ex)
            {
                ServiceEventSource.Current.ServiceMessage(this.serviceContext, ex.Message);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates an PartitionReceiver from the given connection sting and partition key.
        /// The Reliable Dictionaries are used to create a receiver from wherever the service last left off,
        /// or from the current date/time if it's the first time the service is coming up.
        /// </summary>
        /// <param name="client"></param>
        /// <param name="consumerGroup"></param>
        /// <param name="servicePartitionKey"></param>
        /// <param name="epochDictionary"></param>
        /// <param name="offsetDictionary"></param>
        /// <returns>PartitionReceiver</returns>
        private async Task <PartitionReceiver> ConnectToIoTHubAsync(
            EventHubClient client,
            string consumerGroup,
            long servicePartitionKey,
            IReliableDictionary <string, long> epochDictionary,
            IReliableDictionary <string, string> offsetDictionary)
        {
            // This gives each partition its own dedicated TCP connection to IoT Hub.
            var eventHubRuntimeInfo = await client.GetRuntimeInformationAsync();

            PartitionReceiver partitionReceiver;

            // Get an IoT Hub partition ID that corresponds to this partition's low key.
            // This assumes that this service has a partition count 'n' that is equal to the IoT Hub partition count and a partition range of 0..n-1.
            // For example, given an IoT Hub with 32 partitions, this service should be created with:
            // partition count = 32
            // partition range = 0..31
            string eventHubPartitionId = eventHubRuntimeInfo.PartitionIds[servicePartitionKey];

            using (var tx = this.StateManager.CreateTransaction())
            {
                ConditionalValue <string> offsetResult = await offsetDictionary.TryGetValueAsync(tx, "offset", LockMode.Default);

                ConditionalValue <long> epochResult = await epochDictionary.TryGetValueAsync(tx, "epoch", LockMode.Update);

                long newEpoch = epochResult.HasValue
                    ? epochResult.Value + 1
                    : 0;

                if (offsetResult.HasValue)
                {
                    // continue where the service left off before the last failover or restart.
                    ServiceEventSource.Current.ServiceMessage(
                        this.Context,
                        "Creating EventHub listener on partition {0} with offset {1}",
                        eventHubPartitionId,
                        offsetResult.Value);

                    partitionReceiver = client.CreateEpochReceiver(consumerGroup, eventHubPartitionId, EventPosition.FromOffset(offsetResult.Value), newEpoch);
                }
                else
                {
                    // first time this service is running so there is no offset value yet.
                    // start with the current time.
                    ServiceEventSource.Current.ServiceMessage(
                        this.Context,
                        "Creating EventHub listener on partition {0} with offset {1}",
                        eventHubPartitionId,
                        DateTime.UtcNow);

                    partitionReceiver = client.CreateEpochReceiver(consumerGroup, eventHubPartitionId, EventPosition.FromEnqueuedTime(DateTime.UtcNow), newEpoch);
                }

                // epoch is recorded each time the service fails over or restarts.
                await epochDictionary.SetAsync(tx, "epoch", newEpoch);

                await tx.CommitAsync();
            }

            return(partitionReceiver);
        }