public AzureServiceBusReceiver(IReceiverClient receiverClient, ISBMessageReceiver messageReceiver, MessageHandlerOptions messageHandlerOptions) { _receiverClient = receiverClient ?? throw new ArgumentNullException(nameof(receiverClient)); _messageReceiver = messageReceiver ?? throw new ArgumentNullException(nameof(messageReceiver)); _messageHandlerOptions = messageHandlerOptions ?? new MessageHandlerOptions(DefaultExceptionReceiverHandler) { AutoComplete = false, /* * In fact, what the property actually means is the maximum about of time they lock renewal will happen for internally on the subscription client. * So if you set this to 24 hours e.g. Timespan.FromHours(24) and your processing was to take 12 hours, it would be renewed. However, if you set * this to 12 hours using Timespan.FromHours(12) and your code ran for 24, when you went to complete the message it would give a lockLost exception * (as I was getting above over shorter intervals!). * * in fact, Microsoft's implementation runs a background task that periodically renews the message lock until it expires. */ MaxAutoRenewDuration = TimeSpan.FromMinutes(10), //should be in fact called "max processing time" MaxConcurrentCalls = 2 }; _autoComplete = _messageHandlerOptions.AutoComplete; //note: we can't use management SDK as it requires high priviledged SP in Azure }
void AddReceiveContextPayloads(ReceiveContext receiveContext, Microsoft.Azure.ServiceBus.Core.IMessageReceiver messageReceiver) { receiveContext.GetOrAddPayload(() => messageReceiver); receiveContext.GetOrAddPayload(() => _context.GetPayload <NamespaceContext>()); receiveContext.GetOrAddPayload(() => _errorTransport); receiveContext.GetOrAddPayload(() => _deadLetterTransport); }
public async Task <(bool Ok, string Message)> IsHealthOk(string queueName) { try { // Only way to check if connection string is correct is try receiving a message, // which isn't possible for topics as don't have a subscription AzureCore.IMessageReceiver receiver = _messageReceiverFactory.Receiver(queueName); IList <Message> message = await receiver.PeekAsync(1); await receiver.CloseAsync(); return(await Task.FromResult((true, string.Empty))); } catch (ServiceBusCommunicationException ex) { return(false, ex.Message); } }
async Task OnMessage(Microsoft.Azure.ServiceBus.Core.IMessageReceiver messageReceiver, Message message, CancellationToken cancellationToken) { if (IsStopping) { await WaitAndAbandonMessage(messageReceiver, message).ConfigureAwait(false); return; } using (var delivery = _tracker.BeginDelivery()) { if (_log.IsDebugEnabled) { _log.DebugFormat("Receiving {0}:{1}({2})", delivery.Id, message.MessageId, _context.EntityPath); } await _messageReceiver.Handle(message, context => AddReceiveContextPayloads(context, messageReceiver)).ConfigureAwait(false); } }
protected async override Task ReceiveMessages <T>(string entityPath, Predicate <T> predicate, TimeSpan timeout) { List <T> messages = new List <T>(); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); AzureCore.IMessageReceiver receiver = _messageReceiverFactory.Receiver(entityPath); _ = Task.Run(() => { if (!cancellationTokenSource.Token.WaitHandle.WaitOne(timeout)) { _messageReceiverFactory.TimedOut(); cancellationTokenSource.Cancel(); } }); try { while (true) { Message message = await receiver.ReceiveAsync(TimeSpan.FromSeconds(5)); try { if (message != null) { await receiver.CompleteAsync(message.SystemProperties.LockToken); string json = null; using (MemoryStream inputStream = new MemoryStream(message.Body)) { using (StreamReader streamReader = new StreamReader(inputStream)) { json = streamReader.ReadToEnd(); } } T messageOfType = JsonConvert.DeserializeObject <T>(json); if (predicate(messageOfType)) { break; } } } catch (JsonSerializationException) { // don't do anything the serialization failed as this is not a message we are interested in } if (cancellationTokenSource.Token.IsCancellationRequested) { break; } } } finally { // cancel timeout cancellationTokenSource.Cancel(); await receiver.CloseAsync(); } }