コード例 #1
0
        /// <summary>
        /// Publishes the specified message.
        /// </summary>
        /// <param name="message">The message.</param>
        public void Publish(Domain.Message message)
        {
            EnsureArg.IsNotNull(message, nameof(message));
            if (message.CorrelationId.IsNullOrEmpty())
            {
                message.CorrelationId = IdGenerator.Instance.Next;
            }

            var loggerState = new Dictionary <string, object>
            {
                [LogEventPropertyKeys.CorrelationId] = message.CorrelationId,
            };

            using (this.logger.BeginScope(loggerState))
            {
                if (message.Id.IsNullOrEmpty())
                {
                    message.Id = IdGenerator.Instance.Next;
                    this.logger.LogDebug($"{{LogKey:l}} set message (id={message.Id})", LogKeys.Messaging);
                }

                if (message.Origin.IsNullOrEmpty())
                {
                    message.Origin = this.options.MessageScope;
                    this.logger.LogDebug($"{{LogKey:l}} set message (origin={message.Origin})", LogKeys.Messaging);
                }

                // TODO: async publish!
                if (this.options.Mediator != null)
                {
                    /*await */
                    this.options.Mediator.Publish(new MessagePublishedDomainEvent(message)).GetAwaiter().GetResult(); /*.AnyContext();*/
                }

                var messageName = message.GetType().PrettyName();
                // TODO: really need non-async Result?
                var serviceBusMessage = new Microsoft.Azure.ServiceBus.Message
                {
                    Label         = messageName,
                    MessageId     = message.Id,
                    CorrelationId = message.CorrelationId.IsNullOrEmpty() ? IdGenerator.Instance.Next : message.CorrelationId,
                    //Body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message)), // TODO: use ISerializer here, compacter messages
                    Body = this.serializer.SerializeToBytes(message),
                    To   = this.options.FilterScope
                };
                serviceBusMessage.UserProperties.AddOrUpdate("Origin", this.options.MessageScope);

                this.logger.LogJournal(LogKeys.Messaging, $"publish (name={{MessageName}}, id={{MessageId}}, origin={{MessageOrigin}}, size={serviceBusMessage.Body.Length.Bytes().ToString("#.##")})", LogEventPropertyKeys.TrackPublishMessage, args: new[] { messageName, message.Id, message.Origin });
                this.logger.LogTraceEvent(LogKeys.Messaging, message.Id, messageName, LogTraceEventNames.Message);

                this.options.Provider.CreateModel().SendAsync(serviceBusMessage).GetAwaiter().GetResult();
            }
        }
コード例 #2
0
        /// <summary>
        /// Publishes the specified message.
        /// </summary>
        /// <param name="message">The message.</param>
        public void Publish(Domain.Message message)
        {
            EnsureArg.IsNotNull(message, nameof(message));
            if (message.CorrelationId.IsNullOrEmpty())
            {
                message.CorrelationId = IdGenerator.Instance.Next;
            }

            var messageName = message.GetType().PrettyName();

            using (this.logger.BeginScope(new Dictionary <string, object>
            {
                [LogPropertyKeys.CorrelationId] = message.CorrelationId
            }))
                using (var scope = this.options.Tracer?.BuildSpan(messageName, LogKeys.AppMessaging, SpanKind.Producer).Activate(this.logger))
                {
                    if (message.Id.IsNullOrEmpty())
                    {
                        message.Id = IdGenerator.Instance.Next;
                        this.logger.LogDebug($"{{LogKey:l}} set message (id={message.Id})", LogKeys.AppMessaging);
                    }

                    if (message.Origin.IsNullOrEmpty())
                    {
                        message.Origin = this.options.MessageScope;
                        this.logger.LogDebug($"{{LogKey:l}} set message (origin={message.Origin})", LogKeys.AppMessaging);
                    }

                    // TODO: really need non-async Result?
                    var serviceBusMessage = new Microsoft.Azure.ServiceBus.Message
                    {
                        Label         = messageName,
                        MessageId     = message.Id,
                        CorrelationId = message.CorrelationId.IsNullOrEmpty() ? IdGenerator.Instance.Next : message.CorrelationId,
                        //Body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message)), // TODO: use ISerializer here, compacter messages
                        Body = this.serializer.SerializeToBytes(message),
                        To   = this.options.FilterScope
                    };

                    if (this.options.Expiration.HasValue)
                    {
                        serviceBusMessage.TimeToLive = this.options.Expiration.Value;
                    }

                    serviceBusMessage.UserProperties.AddOrUpdate("Origin", message.Origin);
                    if (scope?.Span != null)
                    {
                        // propagate the span infos
                        serviceBusMessage.UserProperties.AddOrUpdate("TraceId", scope.Span.TraceId);
                        serviceBusMessage.UserProperties.AddOrUpdate("SpanId", scope.Span.SpanId);
                    }

                    this.logger.LogJournal(LogKeys.AppMessaging, $"message publish: {messageName} (id={{MessageId}}, origin={{MessageOrigin}}, size={serviceBusMessage.Body.Length.Bytes().ToString("#.##")})", LogPropertyKeys.TrackPublishMessage, args: new[] { message.Id, message.Origin });
                    this.logger.LogTrace(LogKeys.AppMessaging, message.Id, messageName, LogTraceNames.Message);

                    var policy = Policy.Handle <Exception>()
                                 .WaitAndRetry(this.options.Retries, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) =>
                    {
                        this.logger.LogWarning(ex, "{LogKey:l} could not publish message: {MessageId} after {Timeout}s ({ExceptionMessage})", LogKeys.AppMessaging, message.Id, $"{time.TotalSeconds:n1}", ex.Message);
                    });

                    policy.Execute(() =>
                    {
                        this.options.Provider.TopicClientFactory().SendAsync(serviceBusMessage).GetAwaiter().GetResult();
                    });

                    // TODO: async publish!
                    if (this.options.Mediator != null)
                    {
                        /*await */
                        this.options.Mediator.Publish(new MessagePublishedDomainEvent(message)).GetAwaiter().GetResult(); /*.AnyContext();*/
                    }
                }
        }