public void Initialize(EntityInfo entity, Func <IncomingMessageDetails, ReceiveContext, Task> callback, Func <Exception, Task> errorCallback, Func <ErrorContext, Task <ErrorHandleResult> > processingFailureCallback, int maximumConcurrency) { receiveMode = settings.Get <ReceiveMode>(WellKnownConfigurationKeys.Connectivity.MessageReceivers.ReceiveMode); incomingCallback = callback; this.errorCallback = errorCallback ?? EmptyErrorCallback; this.processingFailureCallback = processingFailureCallback; this.entity = entity; fullPath = entity.Path; if (entity.Type == EntityType.Subscription) { var topic = entity.RelationShips.First(r => r.Type == EntityRelationShipType.Subscription); fullPath = SubscriptionClient.FormatSubscriptionPath(topic.Target.Path, entity.Path); } var transportTransactionMode = settings.HasExplicitValue <TransportTransactionMode>() ? settings.Get <TransportTransactionMode>() : settings.SupportedTransactionMode(); wrapInScope = transportTransactionMode == TransportTransactionMode.SendsAtomicWithReceive; completionCanBeBatched = !wrapInScope; autoRenewTimeout = settings.Get <TimeSpan>(WellKnownConfigurationKeys.Connectivity.MessageReceivers.AutoRenewTimeout); numberOfClients = settings.Get <int>(WellKnownConfigurationKeys.Connectivity.NumberOfClientsPerEntity); var concurrency = maximumConcurrency / (double)numberOfClients; maxConcurrentCalls = concurrency > 1 ? (int)Math.Round(concurrency, MidpointRounding.AwayFromZero) : 1; if (Math.Abs(maxConcurrentCalls - concurrency) > 0) { logger.InfoFormat("The maximum concurrency on message receiver instance for '{0}' has been adjusted to '{1}', because the total maximum concurrency '{2}' wasn't divisable by the number of clients '{3}'", fullPath, maxConcurrentCalls, maximumConcurrency, numberOfClients); } internalReceivers = new IMessageReceiver[numberOfClients]; onMessageOptions = new OnMessageOptions[numberOfClients]; completion = new MultiProducerConcurrentCompletion <Guid>(1000, TimeSpan.FromSeconds(1), 6, numberOfClients); }
public void Initialize(EntityInfoInternal entity, Func <IncomingMessageDetailsInternal, ReceiveContextInternal, Task> callback, Func <Exception, Task> errorCallback, Action <Exception> criticalError, Func <ErrorContext, Task <ErrorHandleResult> > processingFailureCallback, int maximumConcurrency) { incomingCallback = callback; this.criticalError = criticalError; this.errorCallback = errorCallback ?? EmptyErrorCallback; this.processingFailureCallback = processingFailureCallback; this.entity = entity; fullPath = entity.Path; if (entity.Type == EntityType.Subscription) { var topic = entity.RelationShips.First(r => r.Type == EntityRelationShipTypeInternal.Subscription); fullPath = SubscriptionClient.FormatSubscriptionPath(topic.Target.Path, entity.Path); } wrapInScope = settings.TransportTransactionMode == TransportTransactionMode.SendsAtomicWithReceive; // batching will be applied for transaction modes other than SendsAtomicWithReceive completionCanBeBatched = !wrapInScope; var numberOfClients = settings.NumberOfClients; var concurrency = maximumConcurrency / (double)numberOfClients; maxConcurrentCalls = concurrency > 1 ? (int)Math.Round(concurrency, MidpointRounding.AwayFromZero) : 1; if (Math.Abs(maxConcurrentCalls - concurrency) > 0) { logger.InfoFormat("The maximum concurrency on message receiver instance for '{0}' has been adjusted to '{1}', because the total maximum concurrency '{2}' wasn't divisable by the number of clients '{3}'", fullPath, maxConcurrentCalls, maximumConcurrency, numberOfClients); } internalReceivers = new IMessageReceiverInternal[numberOfClients]; onMessageOptions = new OnMessageOptions[numberOfClients]; // when we don't batch we don't need the completion infrastructure completion = completionCanBeBatched ? new MultiProducerConcurrentCompletion <Guid>(1000, TimeSpan.FromSeconds(1), 6, numberOfClients) : null; }
protected override void ProcessRecord() { string[] chunks = Context.ChunkPath(this.SessionState.Path.CurrentLocation); ReceiveMode mode = this.PeekLock.IsPresent ? ReceiveMode.PeekLock : ReceiveMode.ReceiveAndDelete; string path = this.From; if (chunks[0] == "Topics") { path = SubscriptionClient.FormatSubscriptionPath(chunks[1], this.From); } BrokeredMessage message = null; MessageReceiver receiver = this.Factory.CreateMessageReceiver(path, mode); try { message = receiver.Receive(TimeSpan.FromSeconds(10)); } finally { // Setting a timer to close the receiver after a minute. User has to complete the message in this time window new Timer(CloseReceiver, (object)receiver, TimeSpan.FromMinutes(1), TimeSpan.FromMilliseconds(-1)); } if (message != null) { message.Properties.Add("Body", message.GetBody <string>()); } this.WriteObject(message); }
public Task <ITriggerBinding> TryCreateAsync(TriggerBindingProviderContext context) { if (context == null) { throw new ArgumentNullException("context"); } ParameterInfo parameter = context.Parameter; ServiceBusTriggerAttribute attribute = parameter.GetCustomAttribute <ServiceBusTriggerAttribute>(inherit: false); if (attribute == null) { return(Task.FromResult <ITriggerBinding>(null)); } string queueName = null; string topicName = null; string subscriptionName = null; string entityPath = null; if (attribute.QueueName != null) { queueName = Resolve(attribute.QueueName); entityPath = queueName; } else { topicName = Resolve(attribute.TopicName); subscriptionName = Resolve(attribute.SubscriptionName); entityPath = SubscriptionClient.FormatSubscriptionPath(topicName, subscriptionName); } ITriggerDataArgumentBinding <BrokeredMessage> argumentBinding = InnerProvider.TryCreate(parameter); if (argumentBinding == null) { throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "Can't bind ServiceBusTrigger to type '{0}'.", parameter.ParameterType)); } string connectionName = ServiceBusAccount.GetAccountOverrideOrNull(context.Parameter); ServiceBusAccount account = new ServiceBusAccount { MessagingFactory = _config.MessagingProvider.CreateMessagingFactory(entityPath, connectionName), NamespaceManager = _config.MessagingProvider.CreateNamespaceManager(connectionName) }; ITriggerBinding binding; if (queueName != null) { binding = new ServiceBusTriggerBinding(parameter.Name, parameter.ParameterType, argumentBinding, account, queueName, attribute.Access, _config); } else { binding = new ServiceBusTriggerBinding(parameter.Name, argumentBinding, account, topicName, subscriptionName, attribute.Access, _config); } return(Task.FromResult <ITriggerBinding>(binding)); }
public ServiceBusTriggerBinding(string parameterName, Type parameterType, ITriggerDataArgumentBinding <BrokeredMessage> argumentBinding, ServiceBusAccount account, AccessRights accessRights, ServiceBusConfiguration config, string topicName, string subscriptionName) : this(parameterName, parameterType, argumentBinding, account, accessRights, config) { _topicName = topicName; _subscriptionName = subscriptionName; _entityPath = SubscriptionClient.FormatSubscriptionPath(topicName, subscriptionName); }
public ServiceBusTriggerBinding(string parameterName, ITriggerDataArgumentBinding <BrokeredMessage> argumentBinding, ServiceBusAccount account, string topicName, string subscriptionName) { _parameterName = parameterName; _argumentBinding = argumentBinding; _account = account; _namespaceName = ServiceBusClient.GetNamespaceName(account); _topicName = topicName; _subscriptionName = subscriptionName; _entityPath = SubscriptionClient.FormatSubscriptionPath(topicName, subscriptionName); }
private void CreateSubscription(ServiceBusConnectionContext connectionContext, int topicIndex) { lock (connectionContext.SubscriptionsLock) { if (connectionContext.IsDisposed) { return; } string topicName = connectionContext.TopicNames[topicIndex]; // Create a random subscription string subscriptionName = Guid.NewGuid().ToString(); try { var subscriptionDescription = new SubscriptionDescription(topicName, subscriptionName); // This cleans up the subscription while if it's been idle for more than the timeout. subscriptionDescription.AutoDeleteOnIdle = _idleSubscriptionTimeout; _namespaceManager.CreateSubscription(subscriptionDescription); _trace.TraceInformation("Creation of a new subscription {0} for topic {1} in the service bus completed successfully.", subscriptionName, topicName); } catch (MessagingEntityAlreadyExistsException) { // The entity already exists _trace.TraceInformation("Creation of a new subscription {0} for topic {1} threw an MessagingEntityAlreadyExistsException.", subscriptionName, topicName); } // Create a receiver to get messages string subscriptionEntityPath = SubscriptionClient.FormatSubscriptionPath(topicName, subscriptionName); MessageReceiver receiver = _factory.CreateMessageReceiver(subscriptionEntityPath, ReceiveMode.ReceiveAndDelete); _trace.TraceInformation("Creation of a message receive for subscription entity path {0} in the service bus completed successfully.", subscriptionEntityPath); connectionContext.SetSubscriptionContext(new SubscriptionContext(topicName, subscriptionName, receiver), topicIndex); var receiverContext = new ReceiverContext(topicIndex, receiver, connectionContext); var task = Task.Run(() => ProcessMessages(receiverContext)); _processMessagesTasks.GetOrAdd(task, false); task.ContinueWith(t => { bool value; _processMessagesTasks.TryRemove(task, out value); }); // Open the stream connectionContext.OpenStream(topicIndex); } }
public async Task <IListener> CreateAsync(IFunctionExecutor executor, CancellationToken cancellationToken) { // Must create all messaging entities before creating message receivers and calling OnMessage. // Otherwise, some function could start to execute and try to output messages to entities that don't yet // exist. await _namespaceManager.CreateTopicIfNotExistsAsync(_topicName, cancellationToken); await _namespaceManager.CreateSubscriptionIfNotExistsAsync(_topicName, _subscriptionName, cancellationToken); string entityPath = SubscriptionClient.FormatSubscriptionPath(_topicName, _subscriptionName); ITriggerExecutor <BrokeredMessage> triggerExecutor = new ServiceBusTriggerExecutor(_instanceFactory, executor); return(new ServiceBusListener(_messagingFactory, entityPath, triggerExecutor)); }
internal static async Task <ISubscription> ForAsync(AzureServiceBusConfiguration configuration, Type eventType, string subscriptionName) { var topicPath = Conventions.TopicPath(eventType); var namespaceManager = NamespaceManager.CreateFromConnectionString(configuration.ConnectionString); var subscriptionExists = await namespaceManager.SubscriptionExistsAsync(topicPath, subscriptionName); if (!subscriptionExists) { await namespaceManager.CreateSubscriptionAsync(topicPath, subscriptionName); } var messagingFactory = MessagingFactory.CreateFromConnectionString(configuration.ConnectionString); var subscriptionPath = SubscriptionClient.FormatSubscriptionPath(topicPath, subscriptionName); var receiver = await messagingFactory.CreateMessageReceiverAsync(subscriptionPath, ReceiveMode.PeekLock); return(new Subscription(receiver, eventType)); }
public override void Listen(Channel channel, Action <object>[] routeactions, string channelpath) { var client = SubscriptionClient.CreateFromConnectionString(channel.ToConnectionString, channel.ToPath, channel.ToSubscription); var path = SubscriptionClient.FormatSubscriptionPath(channel.ToPath, channel.ToSubscription); var receiver = client.MessagingFactory.CreateMessageReceiver(path); var options = CreateOptions(); Action <BrokeredMessage> routeaction = message => { foreach (var action in routeactions) { var clone = message.Clone(); action(clone); } }; receiver.OnMessage(bm => OnMessage(channelpath, bm.MessageId, () => routeaction(bm), () => client.Complete(bm.LockToken)), options); channel.Shutdown = () => { receiver.Close(); client.Close(); }; }
void GetEntityData(bool deadLetterQueueData, out long messageCount, out string entityPath) { if (deadLetterQueueData) { if (queueDescription != null) { var queueDescription2 = serviceBusHelper.GetQueue(queueDescription.Path); messageCount = queueDescription2.MessageCountDetails.DeadLetterMessageCount; entityPath = QueueClient.FormatDeadLetterPath(queueDescription.Path); } else { var subscriptionDescription = serviceBusHelper.GetSubscription(subscriptionWrapper.TopicDescription.Path, subscriptionWrapper.SubscriptionDescription.Name); messageCount = subscriptionDescription.MessageCountDetails.DeadLetterMessageCount; entityPath = SubscriptionClient.FormatDeadLetterPath(subscriptionWrapper.SubscriptionDescription.TopicPath, subscriptionWrapper.SubscriptionDescription.Name); } } else { if (queueDescription != null) { var queueDescription2 = serviceBusHelper.GetQueue(queueDescription.Path); messageCount = queueDescription2.MessageCountDetails.ActiveMessageCount; entityPath = queueDescription.Path; } else { var subscriptionDescription = serviceBusHelper.GetSubscription(subscriptionWrapper.TopicDescription.Path, subscriptionWrapper.SubscriptionDescription.Name); messageCount = subscriptionDescription.MessageCountDetails.ActiveMessageCount; entityPath = SubscriptionClient.FormatSubscriptionPath(subscriptionWrapper.SubscriptionDescription.TopicPath, subscriptionWrapper.SubscriptionDescription.Name); } } }
protected override async Task OnOpenAsync() { var receiverPaths = this.Settings.EntityType == EntityType.Topic ? this.Settings.SubscriptionNames.Select((n) => SubscriptionClient.FormatSubscriptionPath(this.Settings.TopicPath, n)) : new string[] { this.Settings.QueuePath }; foreach (var receiverPath in receiverPaths) { for (int i = 0; i < this.Settings.ReceiverCount; i++) { var factory = MessagingFactory.CreateFromConnectionString(this.ConnectionString); factory.RetryPolicy = RetryPolicy.NoRetry; this.Factories.Add(factory); var receiver = factory.CreateMessageReceiver(receiverPath, this.Settings.ReceiveMode); receiver.RetryPolicy = RetryPolicy.NoRetry; this.receivers.Add(receiver); } } await this.receivers.First().ReceiveAsync(); await this.receivers.ParallelForEachAsync(async (receiver, receiverIndex) => { await Extensions.IgnoreExceptionAsync(async() => await receiver.ReceiveAsync(TimeSpan.Zero)); }); }
public async Task <SubscriptionDescription> Create(string topicPath, string subscriptionName, SubscriptionMetadataInternal metadata, string sqlFilter, INamespaceManagerInternal namespaceManager, string forwardTo = null) { var subscriptionDescription = new SubscriptionDescription(topicPath, subscriptionName) { EnableBatchedOperations = subscriptionSettings.EnableBatchedOperations, AutoDeleteOnIdle = subscriptionSettings.AutoDeleteOnIdle, DefaultMessageTimeToLive = subscriptionSettings.DefaultMessageTimeToLive, EnableDeadLetteringOnFilterEvaluationExceptions = subscriptionSettings.EnableDeadLetteringOnFilterEvaluationExceptions, EnableDeadLetteringOnMessageExpiration = subscriptionSettings.EnableDeadLetteringOnMessageExpiration, LockDuration = subscriptionSettings.LockDuration, MaxDeliveryCount = DefaultMaxDeliveryCountForNoImmediateRetries }; if (subscriptionSettings.ForwardDeadLetteredMessagesToCondition(SubscriptionClient.FormatSubscriptionPath(topicPath, subscriptionName))) { subscriptionDescription.ForwardDeadLetteredMessagesTo = subscriptionSettings.ForwardDeadLetteredMessagesTo; } subscriptionSettings.DescriptionCustomizer(subscriptionDescription); if (!string.IsNullOrWhiteSpace(forwardTo)) { subscriptionDescription.ForwardTo = forwardTo; } subscriptionDescription.UserMetadata = metadata.Description; try { if (!await ExistsAsync(topicPath, subscriptionName, metadata.Description, namespaceManager).ConfigureAwait(false)) { await namespaceManager.CreateSubscription(subscriptionDescription, sqlFilter).ConfigureAwait(false); logger.Info($"Subscription '{subscriptionDescription.UserMetadata}' in namespace '{namespaceManager.Address.Host}' created as '{subscriptionDescription.Name}'."); var key = GenerateSubscriptionKey(namespaceManager.Address, subscriptionDescription.TopicPath, subscriptionDescription.Name); await rememberExistence.AddOrUpdate(key, keyNotFound => TaskEx.CompletedTrue, (updateTopicPath, previousValue) => TaskEx.CompletedTrue).ConfigureAwait(false); } else { logger.Info($"Subscription '{subscriptionDescription.Name}' in namespace '{namespaceManager.Address.Host}' aka '{subscriptionDescription.UserMetadata}' already exists, skipping creation."); logger.InfoFormat("Checking if subscription '{0}' in namespace '{1}' needs to be updated.", subscriptionDescription.Name, namespaceManager.Address.Host); var existingSubscriptionDescription = await namespaceManager.GetSubscription(subscriptionDescription.TopicPath, subscriptionDescription.Name).ConfigureAwait(false); if (MembersAreNotEqual(existingSubscriptionDescription, subscriptionDescription)) { OverrideImmutableMembers(existingSubscriptionDescription, subscriptionDescription); logger.InfoFormat("Updating subscription '{0}' in namespace '{1}' with new description.", subscriptionDescription.Name, namespaceManager.Address.Host); await namespaceManager.UpdateSubscription(subscriptionDescription).ConfigureAwait(false); } } } catch (MessagingEntityAlreadyExistsException) { // the subscription already exists or another node beat us to it, which is ok logger.InfoFormat("Subscription '{0}' in namespace '{1}' already exists, another node probably beat us to it.", subscriptionDescription.Name, namespaceManager.Address.Host); } catch (TimeoutException) { logger.InfoFormat("Timeout occurred on subscription creation for topic '{0}' subscription name '{1}' in namespace '{2}' going to validate if it doesn't exist.", subscriptionDescription.TopicPath, subscriptionDescription.Name, namespaceManager.Address.Host); // there is a chance that the timeout occurred, but the topic was still created, check again if (!await ExistsAsync(subscriptionDescription.TopicPath, subscriptionDescription.Name, metadata.Description, namespaceManager, removeCacheEntry: true).ConfigureAwait(false)) { throw; } logger.InfoFormat("Looks like subscription '{0}' in namespace '{1}' exists anyway.", subscriptionDescription.Name, namespaceManager.Address.Host); } catch (MessagingException ex) { var loggedMessage = $"{(ex.IsTransient ? "Transient" : "Non transient")} {ex.GetType().Name} occurred on subscription '{subscriptionDescription.Name}' creation for topic '{subscriptionDescription.TopicPath}' in namespace '{namespaceManager.Address.Host}'."; if (!ex.IsTransient) { logger.Fatal(loggedMessage, ex); throw; } logger.Info(loggedMessage, ex); } return(subscriptionDescription); }
/*private static async Task MainAsync() * { * queueClient = new QueueClient(ServiceBusConnectionString, QueueName, ReceiveMode.PeekLock); * ReceiveMessages(); * * Console.WriteLine("Press any key to stop receiving messages."); * Console.ReadKey(); * * // Close the client after the ReceiveMessages method has exited. * await queueClient.CloseAsync(); * }*/ private void GetMessages(/*bool peek, bool all, int count*/) { bool peek = false; bool all = true; int count = iMessageCount; SetLogText("Delete Process Starts"); try { var brokeredMessages = new List <BrokeredMessage>(); if (peek) { var subscriptionClient = serviceBusHelper.MessagingFactory.CreateSubscriptionClient(strTopic, strSubscription, ReceiveMode.PeekLock); var totalRetrieved = 0; while (totalRetrieved < count) { var messageEnumerable = subscriptionClient.PeekBatch(count); if (messageEnumerable == null) { break; } var messageArray = messageEnumerable as BrokeredMessage[] ?? messageEnumerable.ToArray(); var partialList = new List <BrokeredMessage>(messageArray); brokeredMessages.AddRange(partialList); totalRetrieved += partialList.Count; if (partialList.Count == 0) { break; } } //writeToLog(string.Format(MessagesPeekedFromTheSubscription, brokeredMessages.Count, subscriptionWrapper.SubscriptionDescription.Name)); } else { MessageReceiver messageReceiver; /*if (subscriptionWrapper.SubscriptionDescription.RequiresSession) * { * var subscriptionClient = serviceBusHelper.MessagingFactory.CreateSubscriptionClient(strTopic, * strSubscription, * ReceiveMode.ReceiveAndDelete); * * messageReceiver = subscriptionClient.AcceptMessageSession(TimeSpan.FromSeconds(MainForm.SingletonMainForm.ReceiveTimeout)); * } * else*/ { messageReceiver = serviceBusHelper.MessagingFactory.CreateMessageReceiver(SubscriptionClient.FormatSubscriptionPath( strTopic, strSubscription), ReceiveMode.ReceiveAndDelete); SetLogText("Message Receiver Created"); } SetLogText("Need to delete: " + count); var totalRetrieved = 0; int retrieved; do { var messages = messageReceiver.ReceiveBatch(10, TimeSpan.FromSeconds(1)); var enumerable = messages as BrokeredMessage[] ?? messages.ToArray(); retrieved = enumerable.Count(); SetLogText("Retrived: " + retrieved); if (retrieved == 0) { continue; } totalRetrieved += retrieved; SetMessagesDeletedText(totalRetrieved.ToString()); brokeredMessages.AddRange(enumerable); SetProgress(retrieved); SetLogText("Total Retrived: " + totalRetrieved); } while (retrieved > 0 && (all || count > totalRetrieved)); SetMessagesDeletedText(totalRetrieved.ToString()); SetProgress(retrieved); } messageBindingList = new SortableBindingList <BrokeredMessage>(brokeredMessages) { AllowEdit = false, AllowNew = false, AllowRemove = false }; } catch (TimeoutException ex) { SetLogText("TimeoutException: " + ex.Message); } catch (NotSupportedException ex) { SetLogText("NotSupportedException: " + ex.Message);//ReadMessagesOneAtTheTime(peek, all, count, messageInspector); } catch (Exception ex) { SetLogText("Exception: " + ex.Message);//HandleException(ex); } finally { SetLogText("Process Complete !!!!!"); /*mainTabControl.ResumeLayout(); * mainTabControl.ResumeDrawing(); * tabPageMessages.ResumeLayout(); * tabPageMessages.ResumeDrawing(); * Cursor.Current = Cursors.Default;*/ } }
protected override IEnumerator <AsyncStep> GetAsyncSteps() { this.owner.namespaceManager = this.serviceBusFactory.CreateNamespaceManager(); for (int partitionId = 0; partitionId < this.owner.partitionCount; partitionId++) { // Create topic if not exists. string topicPath = this.owner.GetTopicPath(partitionId); bool topicExist = false; yield return(this.CallAsync( (thisPtr, t, c, s) => thisPtr.owner.namespaceManager.BeginTopicExists(topicPath, c, s), (thisPtr, r) => topicExist = thisPtr.owner.namespaceManager.EndTopicExists(r), ExceptionPolicy.Transfer)); if (!topicExist) { TopicDescription topicDescription = new TopicDescription(topicPath); yield return(this.CallAsync( (thisPtr, t, c, s) => thisPtr.owner.namespaceManager.BeginCreateTopic(topicDescription, c, s), (thisPtr, r) => topicDescription = thisPtr.owner.namespaceManager.EndCreateTopic(r), ExceptionPolicy.Transfer)); } for (int nodeId = 0; nodeId < this.owner.nodeCount; nodeId++) { // Create subscriptions if not exist string subscriptionName = GetSubscriptionName(nodeId); bool subscriptionExists = false; yield return(this.CallAsync( (thisPtr, t, c, s) => thisPtr.owner.namespaceManager.BeginSubscriptionExists(topicPath, subscriptionName, c, s), (thisPtr, r) => subscriptionExists = thisPtr.owner.namespaceManager.EndSubscriptionExists(r), ExceptionPolicy.Transfer)); if (!subscriptionExists) { SubscriptionDescription subscriptionDescription = new SubscriptionDescription(topicPath, subscriptionName) { RequiresSession = false }; yield return(this.CallAsync( (thisPtr, t, c, s) => thisPtr.owner.namespaceManager.BeginCreateSubscription(subscriptionDescription, c, s), (thisPtr, r) => thisPtr.owner.namespaceManager.EndCreateSubscription(r), ExceptionPolicy.Transfer)); } } } for (int partitionId = 0; partitionId < this.owner.partitionCount; partitionId++) { MessagingFactory factory = null; yield return(this.CallAsync( (thisPtr, t, c, s) => thisPtr.serviceBusFactory.BeginCreateMessagingFactory(c, s), (thisPtr, r) => factory = thisPtr.serviceBusFactory.EndCreateMessagingFactory(r), ExceptionPolicy.Transfer)); this.owner.factories.Add(partitionId, factory); string topicPath = this.owner.GetTopicPath(partitionId); string subscriptionName = GetSubscriptionName(this.owner.nodeId); string subscriptionEntityPath = SubscriptionClient.FormatSubscriptionPath(topicPath, subscriptionName); MessageSender sender = null; yield return(this.CallAsync( (thisPtr, t, c, s) => factory.BeginCreateMessageSender(topicPath, c, s), (thisPtr, r) => sender = factory.EndCreateMessageSender(r), ExceptionPolicy.Transfer)); this.owner.senders.Add(partitionId, sender); MessageReceiver receiver = null; yield return(this.CallAsync( (thisPtr, t, c, s) => factory.BeginCreateMessageReceiver(subscriptionEntityPath, ReceiveMode.ReceiveAndDelete, c, s), (thisPtr, r) => receiver = factory.EndCreateMessageReceiver(r), ExceptionPolicy.Transfer)); var pump = new MessagePump(topicPath, receiver, this.owner.inputQueue, this.owner.semaphore); this.owner.pumps.Add(partitionId, pump); pump.Start(); } this.owner.dispatcher = new MessageDispatcher(this.owner.inputQueue, this.owner.onReceivedAsync); this.owner.dispatcher.Start(); }
private void GetMessages(bool peek, bool all, int count, SubscriptionWrapper SW) { try { var brokeredMessages = new List <BrokeredMessage>(); if (peek) { var subscriptionClient = serviceBusHelper.MessagingFactory.CreateSubscriptionClient(SW.SubscriptionDescription.TopicPath, SW.SubscriptionDescription.Name, ReceiveMode.PeekLock); var totalRetrieved = 0; while (totalRetrieved < count) { var messageEnumerable = subscriptionClient.PeekBatch(count); if (messageEnumerable == null) { break; } IBrokeredMessageInspector messageInspector = null; var messageArray = messageEnumerable as BrokeredMessage[] ?? messageEnumerable.ToArray(); var partialList = new List <BrokeredMessage>(messageArray); brokeredMessages.AddRange(partialList); totalRetrieved += partialList.Count; if (partialList.Count == 0) { break; } else { for (int iIndex = 0; iIndex < partialList.Count; iIndex++) { BrokeredMessage bMsg = partialList[iIndex]; int x = 0; } } } //writeToLog(string.Format(MessagesPeekedFromTheSubscription, brokeredMessages.Count, subscriptionWrapper.SubscriptionDescription.Name)); } else { MessageReceiver messageReceiver; if (SW.SubscriptionDescription.RequiresSession) { var subscriptionClient = serviceBusHelper.MessagingFactory.CreateSubscriptionClient(SW.SubscriptionDescription.TopicPath, SW.SubscriptionDescription.Name, ReceiveMode.ReceiveAndDelete); //messageReceiver = subscriptionClient.AcceptMessageSession(TimeSpan.FromSeconds(MainForm.SingletonMainForm.ReceiveTimeout)); } else { messageReceiver = serviceBusHelper.MessagingFactory.CreateMessageReceiver(SubscriptionClient.FormatSubscriptionPath( SW.SubscriptionDescription.TopicPath, SW.SubscriptionDescription.Name), ReceiveMode.ReceiveAndDelete); } //writeToLog(string.Format(MessagesReceivedFromTheSubscription, brokeredMessages.Count, subscriptionWrapper.SubscriptionDescription.Name)); } if (!peek) { /*if (OnRefresh != null) * { * OnRefresh(); * }*/ } } catch (TimeoutException) { /*writeToLog(string.Format(NoMessageReceivedFromTheSubscription, * MainForm.SingletonMainForm.ReceiveTimeout, * subscriptionWrapper.SubscriptionDescription.Name));*/ int x = 0; } }
public ServiceBusSubscription Subscribe(IList <string> topicNames, Action <int, IEnumerable <BrokeredMessage> > handler, Action <int, Exception> errorHandler) { if (topicNames == null) { throw new ArgumentNullException("topicNames"); } if (handler == null) { throw new ArgumentNullException("handler"); } _trace.TraceInformation("Subscribing to {0} topic(s) in the service bus...", topicNames.Count); var subscriptions = new ServiceBusSubscription.SubscriptionContext[topicNames.Count]; var clients = new TopicClient[topicNames.Count]; for (var topicIndex = 0; topicIndex < topicNames.Count; ++topicIndex) { string topicName = topicNames[topicIndex]; if (!_namespaceManager.TopicExists(topicName)) { try { _trace.TraceInformation("Creating a new topic {0} in the service bus...", topicName); _namespaceManager.CreateTopic(topicName); _trace.TraceInformation("Creation of a new topic {0} in the service bus completed successfully.", topicName); } catch (MessagingEntityAlreadyExistsException) { // The entity already exists _trace.TraceInformation("Creation of a new topic {0} threw an MessagingEntityAlreadyExistsException.", topicName); } } // Create a client for this topic clients[topicIndex] = TopicClient.CreateFromConnectionString(_configuration.ConnectionString, topicName); _trace.TraceInformation("Creation of a new topic client {0} completed successfully.", topicName); // Create a random subscription string subscriptionName = Guid.NewGuid().ToString(); try { var subscriptionDescription = new SubscriptionDescription(topicName, subscriptionName); // This cleans up the subscription while if it's been idle for more than the timeout. subscriptionDescription.AutoDeleteOnIdle = IdleSubscriptionTimeout; _namespaceManager.CreateSubscription(subscriptionDescription); _trace.TraceInformation("Creation of a new subscription {0} for topic {1} in the service bus completed successfully.", subscriptionName, topicName); } catch (MessagingEntityAlreadyExistsException) { // The entity already exists _trace.TraceInformation("Creation of a new subscription {0} for topic {1} threw an MessagingEntityAlreadyExistsException.", subscriptionName, topicName); } // Create a receiver to get messages string subscriptionEntityPath = SubscriptionClient.FormatSubscriptionPath(topicName, subscriptionName); MessageReceiver receiver = _factory.CreateMessageReceiver(subscriptionEntityPath, ReceiveMode.ReceiveAndDelete); _trace.TraceInformation("Creation of a message receive for subscription entity path {0} in the service bus completed successfully.", subscriptionEntityPath); subscriptions[topicIndex] = new ServiceBusSubscription.SubscriptionContext(topicName, subscriptionName, receiver); var receiverContext = new ReceiverContext(topicIndex, receiver, handler, errorHandler); ProcessMessages(receiverContext); } _trace.TraceInformation("Subscription to {0} topics in the service bus Topic service completed successfully.", topicNames.Count); return(new ServiceBusSubscription(_configuration, _namespaceManager, subscriptions, clients)); }
public async Task <SubscriptionDescription> Create(string topicPath, string subscriptionName, SubscriptionMetadataInternal metadata, string sqlFilter, INamespaceManagerInternal namespaceManager, string forwardTo) { if (!(metadata is ForwardingTopologySubscriptionMetadata meta)) { throw new InvalidOperationException($"Cannot create subscription `{subscriptionName}` for topic `{topicPath}` without namespace information required."); } var subscriptionDescription = new SubscriptionDescription(topicPath, subscriptionName) { EnableBatchedOperations = subscriptionSettings.EnableBatchedOperations, AutoDeleteOnIdle = subscriptionSettings.AutoDeleteOnIdle, DefaultMessageTimeToLive = subscriptionSettings.DefaultMessageTimeToLive, EnableDeadLetteringOnFilterEvaluationExceptions = subscriptionSettings.EnableDeadLetteringOnFilterEvaluationExceptions, EnableDeadLetteringOnMessageExpiration = subscriptionSettings.EnableDeadLetteringOnMessageExpiration, LockDuration = subscriptionSettings.LockDuration, MaxDeliveryCount = DefaultMaxDeliveryCountForNoImmediateRetries }; if (subscriptionSettings.ForwardDeadLetteredMessagesToCondition(SubscriptionClient.FormatSubscriptionPath(topicPath, subscriptionName))) { subscriptionDescription.ForwardDeadLetteredMessagesTo = subscriptionSettings.ForwardDeadLetteredMessagesTo; } subscriptionSettings.DescriptionCustomizer(subscriptionDescription); subscriptionDescription.ForwardTo = forwardTo; subscriptionDescription.UserMetadata = metadata.Description; try { var exists = await ExistsAsync(topicPath, subscriptionName, metadata.Description, namespaceManager).ConfigureAwait(false); if (!exists) { var ruleDescription = new RuleDescription { Filter = new SqlFilter(sqlFilter), Name = metadata.SubscriptionNameBasedOnEventWithNamespace }; try { await namespaceManager.CreateSubscription(subscriptionDescription, ruleDescription).ConfigureAwait(false); logger.Info($"Subscription '{subscriptionDescription.UserMetadata}' created as '{subscriptionDescription.Name}' with rule '{ruleDescription.Name}' for event '{meta.SubscribedEventFullName}' in namespace '{namespaceManager.Address.Host}'."); var key = GenerateSubscriptionKey(namespaceManager.Address, subscriptionDescription.TopicPath, subscriptionDescription.Name); await rememberExistence.AddOrUpdate(key, keyNotFound => TaskEx.CompletedTrue, (updateTopicPath, previousValue) => TaskEx.CompletedTrue).ConfigureAwait(false); } catch (MessagingEntityAlreadyExistsException) { // the subscription already exists or another node beat us to it, which is ok logger.Info($"Subscription '{subscriptionDescription.Name}' in namespace '{namespaceManager.Address.Host}' already exists, another node probably beat us to it."); exists = true; } } if (exists) { logger.Info($"Subscription '{subscriptionDescription.Name}' aka '{subscriptionDescription.UserMetadata}' already exists, skipping creation."); logger.InfoFormat("Checking if subscription '{0}' in namespace '{1}' needs to be updated.", subscriptionDescription.Name, namespaceManager.Address.Host); var existingSubscriptionDescription = await namespaceManager.GetSubscription(subscriptionDescription.TopicPath, subscriptionDescription.Name).ConfigureAwait(false); if (MembersAreNotEqual(existingSubscriptionDescription, subscriptionDescription)) { logger.Info($"Updating subscription '{subscriptionDescription.Name}' in namespace '{namespaceManager.Address.Host}' with new description."); await namespaceManager.UpdateSubscription(subscriptionDescription).ConfigureAwait(false); } // Rules can't be queried, so try to add var ruleDescription = new RuleDescription { Filter = new SqlFilter(sqlFilter), Name = metadata.SubscriptionNameBasedOnEventWithNamespace }; logger.Info($"Adding subscription rule '{ruleDescription.Name}' for event '{meta.SubscribedEventFullName}' in namespace '{namespaceManager.Address.Host}'."); try { var subscriptionClient = SubscriptionClient.CreateFromConnectionString(meta.NamespaceInfo.ConnectionString, topicPath, subscriptionName); await subscriptionClient.AddRuleAsync(ruleDescription).ConfigureAwait(false); } catch (MessagingEntityAlreadyExistsException exception) { logger.Debug($"Rule '{ruleDescription.Name}' already exists. Response from the server: '{exception.Message}'."); } } } catch (TimeoutException) { logger.Info($"Timeout occurred on subscription creation for topic '{subscriptionDescription.TopicPath}' subscription name '{subscriptionDescription.Name}' in namespace '{namespaceManager.Address.Host}' going to validate if it doesn't exist."); // there is a chance that the timeout occurred, but the topic was still created, check again if (!await ExistsAsync(subscriptionDescription.TopicPath, subscriptionDescription.Name, metadata.Description, namespaceManager, removeCacheEntry: true).ConfigureAwait(false)) { throw; } logger.Info($"Looks like subscription '{subscriptionDescription.Name}' in namespace '{namespaceManager.Address.Host}' exists anyway."); } catch (MessagingException ex) { var loggedMessage = $"{(ex.IsTransient ? "Transient" : "Non transient")} {ex.GetType().Name} occurred on subscription '{subscriptionDescription.Name}' creation for topic '{subscriptionDescription.TopicPath}' in namespace '{namespaceManager.Address.Host}'."; if (!ex.IsTransient) { logger.Fatal(loggedMessage, ex); throw; } logger.Info(loggedMessage, ex); } return(subscriptionDescription); }
private async void btnStart_Click(object sender, EventArgs e) { try { if (btnStart.Text == StopCaption) { await CancelActions(); btnStart.Text = StartCaption; return; } if (serviceBusHelper != null && ValidateParameters()) { startLog?.Invoke(); btnStart.Enabled = false; Cursor.Current = Cursors.WaitCursor; //***************************************************************************************************** // Retrieve Messaging Factory //***************************************************************************************************** var messagingFactory = serviceBusHelper.MessagingFactory; //***************************************************************************************************** // Initialize Statistics and Manager Action //***************************************************************************************************** actionCount = 0; receiverMessageNumber = 0; receiverMessagesPerSecond = 0; receiverMinimumTime = long.MaxValue; receiverMaximumTime = 0; receiverAverageTime = 0; receiverTotalTime = 0; if (checkBoxReceiverEnableGraph.Checked) { chart.Series.ToList().ForEach(s => s.Points.Clear()); } managerResetEvent = new ManualResetEventSlim(false); Action <CancellationTokenSource> managerAction = cts => { if (cts == null) { return; } try { managerResetEvent.Wait(cts.Token); } catch (OperationCanceledException) { } if (!cts.IsCancellationRequested) { Invoke((MethodInvoker)async delegate { btnStart.Text = StartCaption; await MainForm.SingletonMainForm.RefreshSelectedEntity(); }); } }; Action updateGraphAction = () => { var ok = true; long max = 10; while (!graphCancellationTokenSource.IsCancellationRequested && (actionCount > 1 || ok)) { ok = true; long receiveMessageNumber = 0; long receiveTotalTime = 0; while (ok && receiveMessageNumber < max) { ok = blockingCollection.TryTake(out var tuple, 10); if (ok) { receiveMessageNumber += tuple.Item1; receiveTotalTime += tuple.Item2; if (receiveMessageNumber > max) { max = receiveMessageNumber; } } } if (receiveMessageNumber > 0) { var receiveTuple = new Tuple <long, long, DirectionType>(receiveMessageNumber, receiveTotalTime, DirectionType.Receive); if (InvokeRequired) { Invoke(new UpdateStatisticsDelegate(InternalUpdateStatistics), receiveTuple.Item1, receiveTuple.Item2, receiveTuple.Item3); } else { InternalUpdateStatistics(receiveTuple.Item1, receiveTuple.Item2, receiveTuple.Item3); } } } if (Interlocked.Decrement(ref actionCount) == 0) { managerResetEvent.Set(); } }; AsyncCallback updateGraphCallback = a => { var action = a.AsyncState as Action; if (action != null) { action.EndInvoke(a); if (Interlocked.Decrement(ref actionCount) == 0) { managerResetEvent.Set(); } } }; blockingCollection = new BlockingCollection <Tuple <long, long, DirectionType> >(); //***************************************************************************************************** // Receiving messages from a Subscription //***************************************************************************************************** var currentSubscription = subscriptionWrapper.SubscriptionDescription; if (currentSubscription == null) { throw new ArgumentException(NoSubscriptionSelected); } var currentReceiveMode = cboReceivedMode.Text == PeekLock ? ReceiveMode.PeekLock : ReceiveMode.ReceiveAndDelete; var currentMoveToDeadLetterQueue = checkBoxMoveToDeadLetter.Checked; var currentReadFromDeadLetterQueue = checkBoxReadFromDeadLetter.Checked; try { receiverCancellationTokenSource = new CancellationTokenSource(); receiverCancellationTokenSource = new CancellationTokenSource(); receiverBrokeredMessageInspector = cboReceiverInspector.SelectedIndex > 0 ? Activator.CreateInstance(serviceBusHelper.BrokeredMessageInspectors[cboReceiverInspector.Text]) as IBrokeredMessageInspector : null; Action <int> receiverAction = taskId => { var allSessionsAccepted = false; while (!allSessionsAccepted) { try { MessageReceiver messageReceiver; if (currentReadFromDeadLetterQueue) { messageReceiver = messagingFactory.CreateMessageReceiver(SubscriptionClient.FormatDeadLetterPath(currentSubscription.TopicPath, currentSubscription.Name), currentReceiveMode); } else { if (currentSubscription.RequiresSession) { var subscriptionClient = messagingFactory.CreateSubscriptionClient(currentSubscription.TopicPath, currentSubscription.Name, currentReceiveMode); messageReceiver = subscriptionClient.AcceptMessageSession(TimeSpan.FromSeconds(sessionTimeout)); } else { messageReceiver = messagingFactory.CreateMessageReceiver(SubscriptionClient.FormatSubscriptionPath(currentSubscription.TopicPath, currentSubscription.Name), currentReceiveMode); } } messageReceiver.PrefetchCount = prefetchCount; string traceMessage; if (checkBoxReceiverUseTransaction.Checked) { using (var scope = new TransactionScope()) { serviceBusHelper.ReceiveMessages(messageReceiver, taskId, receiveTimeout, filter, currentMoveToDeadLetterQueue, checkBoxCompleteReceive.Checked, checkBoxDeferMessage.Checked, checkBoxEnableReceiverLogging.Checked, checkBoxReceiverVerboseLogging.Checked, checkBoxReceiverEnableStatistics.Checked, checkBoxReceiveBatch.Checked, receiverBatchSize, checkBoxReceiverThinkTime.Checked, receiverThinkTime, receiverBrokeredMessageInspector, UpdateStatistics, receiverCancellationTokenSource, out traceMessage); var builder = new StringBuilder(traceMessage); if (checkBoxReceiverCommitTransaction.Checked) { scope.Complete(); builder.AppendLine(TransactionCommitted); } else { builder.AppendLine(TransactionAborted); } traceMessage = builder.ToString(); } } else { serviceBusHelper.ReceiveMessages(messageReceiver, taskId, receiveTimeout, filter, currentMoveToDeadLetterQueue, checkBoxCompleteReceive.Checked, checkBoxDeferMessage.Checked, checkBoxEnableReceiverLogging.Checked, checkBoxReceiverVerboseLogging.Checked, checkBoxReceiverEnableStatistics.Checked, checkBoxReceiveBatch.Checked, receiverBatchSize, checkBoxReceiverThinkTime.Checked, receiverThinkTime, receiverBrokeredMessageInspector, UpdateStatistics, receiverCancellationTokenSource, out traceMessage); } if (!string.IsNullOrWhiteSpace(traceMessage)) { writeToLog(traceMessage.Substring(0, traceMessage.Length - 1)); } allSessionsAccepted = !currentSubscription.RequiresSession; } catch (TimeoutException ex) { if (currentSubscription.RequiresSession) { writeToLog(string.Format(NoMoreSessionsToAccept, taskId)); allSessionsAccepted = true; } else { HandleException(ex); } } catch (Exception ex) { HandleException(ex); } } }; // Define Receiver AsyncCallback AsyncCallback receiverCallback = a => { var action = a.AsyncState as Action <int>; if (action != null) { action.EndInvoke(a); if (Interlocked.Decrement(ref actionCount) == 0) { managerResetEvent.Set(); } } }; // Start Receiver Actions for (var i = 0; i < receiverTaskCount; i++) { receiverAction.BeginInvoke(i, receiverCallback, receiverAction); Interlocked.Increment(ref actionCount); } } catch (Exception ex) { HandleException(ex); } if (actionCount > 0) { managerCancellationTokenSource = new CancellationTokenSource(); managerAction.BeginInvoke(managerCancellationTokenSource, null, null); graphCancellationTokenSource = new CancellationTokenSource(); updateGraphAction.BeginInvoke(updateGraphCallback, updateGraphAction); Interlocked.Increment(ref actionCount); btnStart.Text = StopCaption; } } } catch (Exception ex) { HandleException(ex); } finally { btnStart.Enabled = true; Cursor.Current = Cursors.Default; } }
public ServiceBusSubscription Subscribe(IList <string> topicNames, Action <int, IEnumerable <BrokeredMessage> > handler, Action <int, Exception> errorHandler) { if (topicNames == null) { throw new ArgumentNullException("topicNames"); } if (handler == null) { throw new ArgumentNullException("handler"); } var subscriptions = new ServiceBusSubscription.SubscriptionContext[topicNames.Count]; var clients = new TopicClient[topicNames.Count]; for (var topicIndex = 0; topicIndex < topicNames.Count; ++topicIndex) { string topicName = topicNames[topicIndex]; if (!_namespaceManager.TopicExists(topicName)) { try { _namespaceManager.CreateTopic(topicName); } catch (MessagingEntityAlreadyExistsException) { // The entity already exists } } // Create a client for this topic clients[topicIndex] = TopicClient.CreateFromConnectionString(_configuration.ConnectionString, topicName); // Create a random subscription string subscriptionName = Guid.NewGuid().ToString(); try { _namespaceManager.CreateSubscription(topicName, subscriptionName); } catch (MessagingEntityAlreadyExistsException) { // The entity already exists } // Create a receiver to get messages string subscriptionEntityPath = SubscriptionClient.FormatSubscriptionPath(topicName, subscriptionName); MessageReceiver receiver = _factory.CreateMessageReceiver(subscriptionEntityPath, ReceiveMode.ReceiveAndDelete); subscriptions[topicIndex] = new ServiceBusSubscription.SubscriptionContext(topicName, subscriptionName, receiver); var receiverContext = new ReceiverContext(topicIndex, receiver, handler, errorHandler); ProcessMessages(receiverContext); } return(new ServiceBusSubscription(_configuration, _namespaceManager, subscriptions, clients)); }