Exemplo n.º 1
0
        public async Task <TopicDescription> Create(string topicPath, INamespaceManager namespaceManager)
        {
            var topicDescription = topicDescriptionFactory(topicPath, settings);

            try
            {
                if (!await ExistsAsync(topicPath, namespaceManager).ConfigureAwait(false))
                {
                    await namespaceManager.CreateTopic(topicDescription).ConfigureAwait(false);

                    logger.InfoFormat("Topic '{0}' in namespace '{1}' created.", topicDescription.Path, namespaceManager.Address);

                    var key = GenerateTopicKey(topicPath, namespaceManager);

                    await rememberExistence.AddOrUpdate(key, notFoundTopicPath => Task.FromResult(true), (updateTopicPath, previousValue) => Task.FromResult(true)).ConfigureAwait(false);
                }
                else
                {
                    logger.InfoFormat("Topic '{0}' in namespace '{1}' already exists, skipping creation.", topicDescription.Path, namespaceManager.Address);
                    logger.InfoFormat("Checking if topic '{0}' in namespace '{1}' needs to be updated.", topicDescription.Path, namespaceManager.Address);
                    var existingTopicDescription = await namespaceManager.GetTopic(topicDescription.Path).ConfigureAwait(false);

                    if (MembersAreNotEqual(existingTopicDescription, topicDescription))
                    {
                        OverrideImmutableMembers(existingTopicDescription, topicDescription);
                        logger.InfoFormat("Updating topic '{0}' in namespace '{1}' with new description.", topicDescription.Path, namespaceManager.Address);
                        await namespaceManager.UpdateTopic(topicDescription).ConfigureAwait(false);
                    }
                }
            }
            catch (MessagingEntityAlreadyExistsException)
            {
                // the topic already exists or another node beat us to it, which is ok
                logger.InfoFormat("Topic '{0}' in namespace '{1}' already exists, another node probably beat us to it.", topicDescription.Path, namespaceManager.Address);
            }
            catch (TimeoutException)
            {
                logger.InfoFormat("Timeout occurred on topic creation for '{0}' in namespace '{1}' going to validate if it doesn't exist.", topicDescription.Path, namespaceManager.Address);

                // there is a chance that the timeout occurred, but the topic was still created, check again
                if (!await ExistsAsync(topicDescription.Path, namespaceManager, removeCacheEntry: true).ConfigureAwait(false))
                {
                    throw;
                }

                logger.InfoFormat("Looks like topic '{0}' in namespace '{1}' exists anyway.", topicDescription.Path, namespaceManager.Address);
            }
            catch (MessagingException ex)
            {
                var loggedMessage = string.Format("{1} {2} occurred on topic creation '{0}' in namespace {3}.", topicDescription.Path, (ex.IsTransient ? "Transient" : "Non transient"), ex.GetType().Name, namespaceManager.Address);

                if (!ex.IsTransient)
                {
                    logger.Fatal(loggedMessage, ex);
                    throw;
                }

                logger.Info(loggedMessage, ex);
            }

            return(topicDescription);
        }