private async Task <(bool, OperateResult)> SendWithoutRetryAsync(PublishedMessage message) { var startTime = DateTimeOffset.UtcNow; var stopwatch = Stopwatch.StartNew(); var tracingResult = TracingBefore(message.Name, message.Content); var operationId = tracingResult.Item1; var sendValues = tracingResult.Item2 != null ? CommonHelper.AddTracingHeaderProperty(message.Content, tracingResult.Item2) : message.Content; var result = await PublishAsync(message.Name, sendValues); stopwatch.Stop(); if (result.Succeeded) { await SetSuccessfulState(message); TracingAfter(operationId, message.Name, sendValues, startTime, stopwatch.Elapsed); return(false, OperateResult.Success); } else { TracingError(operationId, message, result, startTime, stopwatch.Elapsed); var needRetry = await SetFailedState(message, result.Exception); return(needRetry, OperateResult.Failed(result.Exception)); } }
public static bool TryToRoute(PublishedMessage sender, Subscription receiver, out MessageRoute route, out PublisherSubscriberMismatch mismatch) { route = null; mismatch = null; var transportsMatch = (sender.Transports ?? new string[0]).Contains(receiver.Destination.Scheme); var contentType = SelectContentType(sender, receiver); if (transportsMatch && contentType.IsNotEmpty()) { route = new MessageRoute(sender.DotNetType, receiver.Destination, contentType) { Publisher = sender.ServiceName, Receiver = receiver.ServiceName }; return(true); } mismatch = new PublisherSubscriberMismatch(sender, receiver) { IncompatibleTransports = !transportsMatch, IncompatibleContentTypes = contentType == null }; return(false); }
private bool UpdateMessageForRetry(PublishedMessage message) { var retryBehavior = RetryBehavior.DefaultRetry; var retries = ++message.Retries; message.ExpiresAt = message.Added.AddSeconds(retryBehavior.RetryIn(retries)); var retryCount = Math.Min(_options.FailedRetryCount, retryBehavior.RetryCount); if (retries >= retryCount) { if (retries == _options.FailedRetryCount) { try { _options.FailedThresholdCallback?.Invoke(MessageType.Subscribe, message.Name, message.Content); _logger.SenderAfterThreshold(message.Id, _options.FailedRetryCount); } catch (Exception ex) { _logger.ExecutedThresholdCallbackFailed(ex); } } return(false); } _logger.SenderRetrying(message.Id, retries); return(true); }
public void Publish <T>(T message, Action <IPublishContext <T> > contextCallback) where T : class { PublishedMessage <T> published = null; try { _bus.Publish(message, context => { published = new PublishedMessage <T>(context); contextCallback(context); }); } catch (Exception ex) { if (published != null) { published.SetException(ex); } throw; } finally { if (published != null) { _published.Add(published); _scenario.AddPublished(published); } } }
public void DataStream() { var msg = new PublishedMessage { DataBytes = new byte[] { 1 } }; Assert.AreEqual(1, msg.DataStream.ReadByte()); }
public PublisherSubscriberMismatch(PublishedMessage publisher, Subscription subscription) { MessageType = subscription.MessageType; Publisher = publisher.ServiceName; Subscriber = subscription.ServiceName; SubscriberTransport = subscription.Destination.Scheme; PublishedContentTypes = publisher.ContentTypes; SubscriberContentTypes = subscription.Accept; }
private static string SelectContentType(PublishedMessage sender, Subscription receiver) { var matchingContentTypes = receiver.Accept.Intersect(sender.ContentTypes).ToArray(); // Always try to use the versioned or specific reader/writer if one exists var contentType = matchingContentTypes.FirstOrDefault(x => x != "application/json") ?? matchingContentTypes.FirstOrDefault(); return(contentType); }
public static async Task ChangeStateAsync( this IStateChanger @this, PublishedMessage message, IState state, IStorageConnection connection) { using (var transaction = connection.CreateTransaction()) { @this.ChangeState(message, state, transaction); await transaction.CommitAsync(); } }
public void UpdateMessage(PublishedMessage message) { if (message == null) { throw new ArgumentNullException(nameof(message)); } _dbContext.Set <PublishedMessage>().Update(message); _dbContext.SaveChanges(); }
protected override Task ExecuteAsync(PublishedMessage message, ITransaction transaction, CancellationToken cancel = default(CancellationToken)) { var connection = (InMemoryStorageConnection)ServiceProvider.GetService <IStorageConnection>(); connection.PublishedMessages.Add(message); return(Task.CompletedTask); }
private async Task <bool> SetFailedState(PublishedMessage message, Exception ex) { AddErrorReasonToContent(message, ex); var needRetry = UpdateMessageForRetry(message); await _stateChanger.ChangeStateAsync(message, new FailedState(), _connection); return(needRetry); }
public PublishedMessageEntity(PublishedMessage publishedMessage) { this.Id = publishedMessage.Id; this.Name = publishedMessage.Name; this.Content = publishedMessage.Content; this.Retries = publishedMessage.Retries; this.StatusName = publishedMessage.StatusName; this.Added = publishedMessage.Added; this.ExpiresAt = publishedMessage.ExpiresAt; }
public void Add(PublishedMessage message) { lock (_messages) { if (_messages.Add(message)) { _published.Set(); } } }
public void Publish <T>(string name, T contentObj, string callbackName = null) { var message = new PublishedMessage { Id = SnowflakeId.Default().NextId(), Name = name, Content = Serialize(contentObj, callbackName), StatusName = StatusName.Scheduled }; PublishAsyncInternal(message).GetAwaiter().GetResult(); }
public async Task PublishAsync <T>(string name, T contentObj, string callbackName = null, CancellationToken cancellationToken = default(CancellationToken)) { var message = new PublishedMessage { Id = SnowflakeId.Default().NextId(), Name = name, Content = Serialize(contentObj, callbackName), StatusName = StatusName.Scheduled }; await PublishAsyncInternal(message); }
public void ChangeState(PublishedMessage message, IState state, IStorageTransaction transaction) { var now = DateTime.Now; if (state.ExpiresAfter != null) { message.ExpiresAt = now.Add(state.ExpiresAfter.Value); } else { message.ExpiresAt = null; } message.StatusName = state.Name; state.Apply(message, transaction); transaction.UpdateMessage(message); }
public void use_json_if_that_is_the_only_match() { var published = new PublishedMessage(typeof(Message1)) { ContentTypes = new string[] { "application/json", "app/v2", "app/v3" }, Transports = new string[] { "loopback" } }; var subscription = new Subscription(typeof(Message1), "loopback://one".ToUri()); subscription.Accept = new string[] { "application/json", "app/v4", "app/v5" }; MessageRoute.TryToRoute(published, subscription, out MessageRoute route, out PublisherSubscriberMismatch mismatch) .ShouldBeTrue(); route.ContentType.ShouldBe("application/json"); }
public OperateResult PublishAsync(string keyName, PublishedMessage content) { try { return(_executor.PublishAsync(keyName, content.exchangeName, content.ToJson()).Result); } catch { try { return(_executor.PublishAsync(keyName, content.exchangeName, content.ToJson()).Result); } catch (Exception ex) { return(OperateResult.Failed(ex)); } } }
protected override async Task ExecuteAsync(PublishedMessage message, ITransaction transaction, CancellationToken cancel = default(CancellationToken)) { var dbContext = (DbContext)base.ServiceProvider.GetRequiredService(_options.DbContextType); if (NotUseTransaction) { dbContext.Entry(message).Property("Version").CurrentValue = _options.Version; dbContext.Set <PublishedMessage>().Add(message); await dbContext.SaveChangesAsync(cancel); return; } dbContext.Entry(message).Property("Version").CurrentValue = _options.Version; dbContext.Set <PublishedMessage>().Add(message); await dbContext.SaveChangesAsync(cancel); }
private void TracingError(Guid operationId, PublishedMessage message, OperateResult result, DateTimeOffset startTime, TimeSpan du) { var ex = new PublisherSentFailedException(result.ToString(), result.Exception); _logger.MessagePublishException(message.Id, result.ToString(), ex); var eventData = new BrokerPublishErrorEventData( operationId, "", ServersAddress, message.Name, message.Content, ex, startTime, du); s_diagnosticListener.WritePublishError(eventData); }
public static void WritePublishMessageStoreAfter(this DiagnosticListener @this, Guid operationId, PublishedMessage message, [CallerMemberName] string operation = "") { if (@this.IsEnabled(AfterPublishMessageStore)) { @this.Write(AfterPublishMessageStore, new { OperationId = operationId, Operation = operation, MessageId = message.Id, MessageName = message.Name, MessageContent = message.Content, Timestamp = Stopwatch.GetTimestamp() }); } }
public void UpdateMessage(PublishedMessage message) { if (message == null) { throw new ArgumentNullException(nameof(message)); } var msg = _connection.PublishedMessages.FirstOrDefault(x => message.Id == x.Id); if (msg == null) { return; } msg.Retries = message.Retries; msg.Content = message.Content; msg.ExpiresAt = message.ExpiresAt; msg.StatusName = message.StatusName; }
public void mismatch_with_no_matching_content_types_and_transport() { var published = new PublishedMessage(typeof(Message1)) { ContentTypes = new string[] { "one", "two" }, Transports = new string[] { "jasper" } }; var subscription = new Subscription(typeof(Message1), "fake://one".ToUri()); subscription.Accept = new string[] { "three" }; MessageRoute.TryToRoute(published, subscription, out MessageRoute route, out PublisherSubscriberMismatch mismatch) .ShouldBeFalse(); mismatch.IncompatibleContentTypes.ShouldBeTrue(); mismatch.IncompatibleTransports.ShouldBeTrue(); }
public void mismatch_with_no_matching_content_types() { var published = new PublishedMessage(typeof(Message1)) { ContentTypes = new string[] { "one", "two" } }; var subscription = new Subscription(typeof(Message1), "loopback://one".ToUri()); subscription.Accept = new string[] { "three" }; MessageRoute.TryToRoute(published, subscription, out MessageRoute route, out PublisherSubscriberMismatch mismatch) .ShouldBeFalse(); mismatch.IncompatibleContentTypes.ShouldBeTrue(); mismatch.PublishedContentTypes.ShouldBe(published.ContentTypes); mismatch.SubscriberContentTypes.ShouldBe(subscription.Accept); }
public void MessageID_Is_Unique() { var a = new PublishedMessage { Topics = new[] { "topic" }, Sender = _self, SequenceNumber = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }, DataBytes = new byte[] { 0, 1, 0xfe, 0xff } }; var b = new PublishedMessage { Topics = new[] { "topic" }, Sender = _other, SequenceNumber = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }, DataBytes = new byte[] { 0, 1, 0xfe, 0xff } }; Assert.AreNotEqual(a.MessageId, b.MessageId); }
public async Task <OperateResult> SendAsync(PublishedMessage message) { return(await Task.Run(async() => { bool retry; OperateResult result; do { var executedResult = await SendWithoutRetryAsync(message); result = executedResult.Item2; if (result == OperateResult.Success) { return result; } retry = executedResult.Item1; } while (retry); return result; })); }
//============================================================================ //==================== Before publish store message ==================== //============================================================================ public static Guid WritePublishMessageStoreBefore(this DiagnosticListener @this, PublishedMessage message, [CallerMemberName] string operation = "") { if (@this.IsEnabled(BeforePublishMessageStore)) { var operationId = Guid.NewGuid(); @this.Write(BeforePublishMessageStore, new { OperationId = operationId, Operation = operation, MessageName = message.Name, MessageContent = message.Content }); return(operationId); } return(Guid.Empty); }
public PublishedMessage Send(object message) { string serializedMsg = null; if (Context.Serializer != null) { serializedMsg = Context.Serializer.Serialize(message); } int byteCount; SendIntl(serializedMsg, out byteCount); var publishedMessage = new PublishedMessage(message) { SerializedMessage = serializedMsg, SendTime = DateTime.Now, ByteCount = byteCount }; return(publishedMessage); }
private Result StoreMessage(MessageContext message, PublishedMessage receive) { var queueExector = _selector.GetTopicExector(message.Name); if (queueExector != null) { object reflect = Activator.CreateInstance(queueExector.ImplTypeInfo); var methodInfo = queueExector.MethodInfo; var parameters = methodInfo.GetParameters(); List <object> objParams = new List <object>(); objParams = receive.msgBeanJson.ToModel(objParams); for (int i = 0; i < parameters.Length; i++) { objParams[i] = objParams[i].ToJson().ToModel(parameters[i].ParameterType); } var result = methodInfo.Invoke(reflect, objParams.ToArray()) as Result; return(result); } return(Result.Fail(0)); }
private async Task <List <MessageRoute> > compileRoutes(Type messageType) { var list = new List <MessageRoute>(); var modelWriter = _serializers.WriterFor(messageType); var supported = modelWriter.ContentTypes; foreach (var channel in _channels.AllKnownChannels().Where(x => x.ShouldSendMessage(messageType))) { var contentType = supported.FirstOrDefault(x => x != "application/json") ?? "application/json"; if (contentType.IsNotEmpty()) { list.Add(new MessageRoute(messageType, modelWriter, channel, contentType) { }); } } var subscriptions = await _subscriptions.GetSubscribersFor(messageType); if (subscriptions.Any()) { var published = new PublishedMessage(messageType, modelWriter, _channels); foreach (var subscription in subscriptions) { if (MessageRoute.TryToRoute(published, subscription, out MessageRoute route, out PublisherSubscriberMismatch mismatch)) { route.Writer = modelWriter[route.ContentType]; route.Channel = _channels.GetOrBuildChannel(route.Destination); list.Add(route); } else { _logger.SubscriptionMismatch(mismatch); } }
public void AddPublished(PublishedMessage message) { _published.Add(message); }