public long PublishAsync(string channel, string value) { if (pubSub.PublishAsync(channel, value) == 0) { //订阅者为0,或者订阅者出现异常,我们可以重试 RepeatAction(channel, () => { return(pubSub.PublishAsync(channel, value) > 0); }); } return(0); }
private Task InvalidateAsync(params string[] keys) { if (options.WaitForAcknowledgment) { return(pubSub.PublishAsync(CreateMessage(keys))); } else { pubSub.PublishAsync(CreateMessage(keys)); return(Task.CompletedTask); } }
public async Task Should_be_able_to_publish_struct() { var message = DateTime.UtcNow; var messageType = typeof(DateTime); await pubSub.PublishAsync(message, messageType, configure); #pragma warning disable 4014 pubSub.Received() .PublishAsync( Arg.Is(message), Arg.Is(configure), Arg.Any <CancellationToken>() ); #pragma warning restore 4014 }
/// <summary> /// Publishes a message with a topic. /// When used with publisher confirms the task completes when the publish is confirmed. /// Task will throw an exception if the confirm is NACK'd or times out. /// </summary> /// <typeparam name="T">The message type</typeparam> /// <param name="pubSub">The pubSub instance</param> /// /// <param name="message">The message to publish</param> /// <param name="topic">The topic string</param> /// <param name="cancellationToken">The cancellation token</param> /// <returns></returns> public static Task PublishAsync <T>(this IPubSub pubSub, T message, string topic, CancellationToken cancellationToken = default) { Preconditions.CheckNotNull(pubSub, "pubSub"); Preconditions.CheckNotNull(topic, "topic"); return(pubSub.PublishAsync(message, c => c.WithTopic(topic), cancellationToken)); }
/// <summary> /// Publishes a message. /// </summary> /// <typeparam name="T">The message type</typeparam> /// <param name="pubSub">The pubSub instance</param> /// <param name="message">The message to publish</param> /// <param name="configure"> /// Fluent configuration e.g. x => x.WithTopic("*.brighton").WithPriority(2) /// </param> /// <param name="cancellationToken">The cancellation token</param> public static void Publish <T>(this IPubSub pubSub, T message, Action <IPublishConfiguration> configure, CancellationToken cancellationToken = default) { Preconditions.CheckNotNull(pubSub, "pubSub"); pubSub.PublishAsync(message, configure, cancellationToken) .GetAwaiter() .GetResult(); }
public async Task Should_not_send_invalidation_message_when_not_enabled() { options.Enable = false; await sut.RemoveAsync("Key"); A.CallTo(() => pubSub.PublishAsync(A <object> ._)) .MustNotHaveHappened(); }
public static async Task PublishBatchAsync <T>( this IPubSub pubSub, IEnumerable <T> messages, Action <IPublishConfiguration> configuration, CancellationToken cancellationToken = default ) { foreach (var message in messages) { await pubSub.PublishAsync(message, configuration, cancellationToken).ConfigureAwait(false); } }
public static async Task PublishBatchInParallelAsync <T>( this IPubSub pubSub, IEnumerable <T> messages, CancellationToken cancellationToken = default ) { var publishTasks = new List <Task>(); foreach (var message in messages) { publishTasks.Add(pubSub.PublishAsync(message, cancellationToken)); } await Task.WhenAll(publishTasks).ConfigureAwait(false); }
/// <summary> /// Publishes a message with a topic. /// When used with publisher confirms the task completes when the publish is confirmed. /// Task will throw an exception if the confirm is NACK'd or times out. /// </summary> /// <param name="pubSub">The pubSub instance</param> /// <param name="message">The message to publish</param> /// <param name="messageType">The message type</param> /// <param name="cancellationToken">The cancellation token</param> /// <returns></returns> public static Task PublishAsync(this IPubSub pubSub, object message, Type messageType, CancellationToken cancellationToken = default) { Preconditions.CheckNotNull(pubSub, "pubSub"); return(pubSub.PublishAsync(message, messageType, c => { }, cancellationToken)); }
public async Task OnMessageAsync(IMessage message) { if (message == null) { throw new ArgumentNullException(nameof(message)); } var badMessageNextLevel = TopicNameHelpers.ExtractBadMessageNextLevel(message.Topic); string badMessageNextLevelTopicName; if (badMessageNextLevel == badMessageMaxLevels) { badMessageNextLevelTopicName = TopicNameHelpers.BuildDeadLetterTopicName(message.Topic, groupId); } else { badMessageNextLevelTopicName = TopicNameHelpers.BuildBadMessageTopicName(message.Topic, badMessageNextLevel, groupId); } var attempts = new List <Attempt>(); var badMessageCandidate = message; message = GetSourceMessage(badMessageCandidate, attempts); // If message is null, retry time not ellapsed so will ignore this message for now. // It will be read again latter if (message != null) { try { await onMessageAsync.Invoke(new PunchyMessage() { MessageAddress = message.MessageAddress, MessageBytes = message.MessageBytes, Timestamp = message.Timestamp, Topic = message.Topic, Attempts = attempts }); } catch (Exception exception) { if (badMessageNextLevel < badMessageMaxLevels) { logger.LogWarning(exception, "Action failed for message, moving to bad message level '{BadMessageNextLevel}'. " + "Will try again in {RetrySeconds}. Topic: {Topic}; Original message address: {@MessageAddress}", badMessageNextLevel, configuration.LevelDelaysInSeconds[badMessageNextLevel], message.Topic, message.MessageAddress); } else // is final level { logger.LogError(exception, "Action failed for message, will NOT try again. Topic: {Topic}; Original message address: {@MessageAddress}", message.Topic, message.MessageAddress); } var badMessageContents = new BadMessageContents() { Exception = exception, SourceMessageAddress = badMessageCandidate.MessageAddress }; await pubSub.PublishAsync(badMessageNextLevelTopicName, Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(badMessageContents))); } await badMessageCandidate.CommitAsync(); } }