public async Task WriteMessage(string queueName, Type type, object message, DateTime?notBefore = null) { if (message == null) { throw new ArgumentNullException(nameof(message), $"{nameof(message)} must not be null."); } if (type == null) { throw new ArgumentNullException(nameof(type), $"{nameof(type)} must not be null."); } if (string.IsNullOrWhiteSpace(queueName)) { throw new ArgumentNullException($"{nameof(queueName)} must not be null and not empty."); } if (notBefore.HasValue && notBefore.Value.Kind == DateTimeKind.Unspecified) { throw new ArgumentException($"{nameof(notBefore)} must not have an Unspecified DateTimeKind.", nameof(notBefore)); } // note the type in the headers so it can be deserialized. var headers = new Headers { MessageClass = type.FullName + ", " + type.Assembly.GetName().Name }; // create the message entity, serializing the headers and body. var qm = new Model.QueueMessage { MessageId = Guid.NewGuid(), NotBefore = notBefore.HasValue ? notBefore.Value.ToUniversalTime() : _clock.UtcNow, Enqueued = _clock.UtcNow, Completed = null, Failed = null, Retries = 0, Headers = _serializer.SerializeHeaders(headers), Body = _serializer.SerializeMessage(message, type) }; _counters.SentMessage(); // store the message in the queue. await _dataAccess.AddMessage(qm, queueName); }
/// <summary> /// Publishes the message /// </summary> /// <param name="category"></param> /// <param name="type"></param> /// <param name="message"></param> /// <param name="notBefore"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException"></exception> public async Task Publish(string category, Type type, object message, DateTime?notBefore = null) { if (message == null) { throw new ArgumentNullException(nameof(message), $"{nameof(message)} must not be null."); } if (string.IsNullOrWhiteSpace(category)) { throw new ArgumentException($"{nameof(category)} must not be null and not empty."); } if (type == null) { throw new ArgumentNullException(nameof(type), $"{nameof(type)} must not be null."); } if (notBefore.HasValue && notBefore.Value.Kind == DateTimeKind.Unspecified) { throw new ArgumentException($"{nameof(notBefore)} must not have an Unspecified DateTimeKind.", nameof(notBefore)); } // expire any out of data subscribers so we don't waste resources // sending to subscribers that are not renewing their subscriptions. await _dataAccess.ExpireSubscriptions(); // get a list of all subscribers for the category var subscribers = await _dataAccess.GetSubscribers(category); // note the type in the headers so it can be deserialized. var headers = new Headers { MessageClass = type.FullName + ", " + type.Assembly.GetName().Name }; var validUntil = notBefore.HasValue ? notBefore.Value.ToUniversalTime().Add(_subscribedLifespan.Duration) : _clock.UtcNow.Add(_subscribedLifespan.Duration); var nb = notBefore.HasValue ? notBefore.Value.ToUniversalTime() : _clock.UtcNow; var headerstring = _serializer.SerializeHeaders(headers); var bodystring = _serializer.SerializeMessage(message, type); foreach (var subscriber in subscribers) { // create the message entity, serializing the headers and body. var sm = new Model.SubscribedMessage { ValidUntil = validUntil, SubscriberId = subscriber, MessageId = Guid.NewGuid(), NotBefore = nb, Enqueued = _clock.UtcNow, Completed = null, Failed = null, Retries = 0, Headers = headerstring, Body = bodystring }; await _dataAccess.AddMessage(sm); _counters.SentMessage(); } }