Can a sync message have an async message as a response instead of a reply message? - uml

The first picture shows the sync message exportDeclaration(id) waiting for a reply message download(file).
The second picture, I used an async call as a response to the sync message exportDeclaration(id).
I couldn't find anything to know which method is the right one.

Sure it can. When you send an async message it will not take notice of the receiver looking at it. It's fire and forget. A sychronous message has a direct response so you know the receiver got it. In case you expect not the result directly (but only the receipt confirmation) you can go on in the code and react to some later async message from the receiver of the message. It's just more difficult to implement but perfectly possible.

Related

Can we turn messages from Dead Letter queue to Active message?

I have dot net code which read loan-numbers from Azure service queue and calls my API for each loan-number.
This is my code which calls the api
private async Task ProcessMessagesAsync(Message message, CancellationToken token)
{
try
{
string loanNumber = Encoding.UTF8.GetString(message.Body);
_logger.LogInformation($"Received message: SequenceNumber:{message.SystemProperties.SequenceNumber} LoanNumber:{loanNumber}");
//API CALL HERE
await _apiClient.getResult(loanNumber);
await _queueClient.CompleteAsync(message.SystemProperties.LockToken);
}
catch (Exception ex)
{
//sending failed messages to Dead Letter queue
await _queueClient.AbandonAsync(message.SystemProperties.LockToken);
}
}
Failed loan-numbers are successfully sent to Dead Letter queue. When the server is down or bad request from API response.
I want to call the api after certain duration on the loan-numbers which are in Dead Letter Queue.
Is there any way to convert the messages in Dead Letter queue to active messages after some interval??
I am new to azure. Please help me to resolve the issue.
Thanks in advance.
Is there any way to convert the messages in Dead Letter queue to
active messages after some interval??
Automatically, no. However what you could do is read the messages from dead letter queue and then post them as new message in your main queue.
As far as automating the whole process, one possible solution would be to run a timer triggered Azure Function that reads messages from a dead letter queue periodically and post them in your main queue.
#akhil, it's worth noting that these messages will automatically be re-queued on the main queue until their DeliveryCount exceeds the MaxDeliveryCount of your main queue. The default value for MaxDeliveryCount is 10 so any failed requests to the API be retried ten times by this handler before being moved to the DLQ.
If you wanted to be a bit 'smarter' about this you could delay the retries using the Scheduled​Enqueue​Time​Utc property on the message in your catch block.
As #Gaurav Mantri has said, the framework offers nothing to process dead-letter messages 'for free'; you'll have to code a handler yourself as you would for a normal queue.
No, there is no way to convert the DLQ message to active message.
you need to process the DLQ and fix the reason as to why it ended in DLQ and then re transmit it back to your queue.
A sample from Github can be useful here.
https://github.com/Azure/azure-service-bus/tree/master/samples/DotNet/Microsoft.ServiceBus.Messaging/DeadletterQueue
(This sample shows how to move messages to the Dead-letter queue, how to retrieve messages from it, and resubmit corrected message back into the main queue.)
This could be an old answer but we can use ServiceBusExplorer from Microsoft. It can pull the messages from dead letter queue and then those can be requeued using
Let me know if you have any further questions.

Run a function when a ClientEmitter has an error

I'm using an event handler, where each event code is in it's own files. I'm attaching the events to the client, so when that file has the event emitted, it will run that code:
// looping through all event files
client.on(file.split('.')[0], require(`events/${file}`).bind(null, client, Util);
If the event file was message.js, it would be similar to:
client.on('message', require('events/message.js').bind(null, client, Util);
So when the message event is emitted, it runs the message.js file, passing along the client and Util classes.
I also have a function that is attached to the client called report. It basically reports when there is an error. I would like it so whenever any event from the client has an error, it will run that function.
I've done this slightly with the commands: command.run(...).catch(error => client.report(error)).
Is there a similar way to do this, instead of having to put a try-catch around all code in all the event files?
Try this way
client.on('error', require('events/report.js').bind(null, client, Util);
Error handling should be context driven. This means your bot's response to the error should be dependent on what it was doing, in what channel, etc - both for debugging and for the end user's information on what happened. You'll miss out on all of the context by letting errors just travel all the way up into an uncaught exception, and without the ability to create an error message, the user will just see the bot not respond and think it's down or the command is broken.
My suggestion: Create helper methods for your most common error producing functions that wrap them with error handling. I did this mostly for sending messages, as there's a myriad of things that could cause a message send to fail out of your control and the handling consists of generating an error message and attempting to send it in the channel or DM it to the user if that fails.

The remote server returned an error: (404) Not Found While deleting message from queue

We are using Azure Queue for our printing job but when deleting message from queue by queue.DeleteMessage(message), the method throws below exception.
The remote server returned an error: (404) Not Found
Above exception was handled but still looking for workaround.
Can anyone please suggest how to fix it.
Thanks,
Sneh
According to this article, we can find that:
After a client retrieves a message with the Get Messages operation,
the client is expected to process and delete the message. To delete
the message, you must have two items of data returned in the response
body of the Get Messages operation:
The message ID, an opaque GUID value that identifies the message in the queue.
A valid pop receipt, an opaque value that indicates that the message has been retrieved.
If a message with a matching pop receipt is not found, the service returns error code 404 (Not Found). And Pop receipts remain valid until one of the following events occurs:
The message has expired.
The message has been deleted using the last pop receipt received
either from Get Messages or Update Message.
The invisibility timeout has elapsed and the message has been
dequeued by a Get Messages request. When the invisibility timeout
elapses, the message becomes visible again. If it is retrieved by
another Get Messages request, the returned pop receipt can be used
to delete or update the message.
The message has been updated with a new visibility timeout. When the
message is updated, a new pop receipt will be returned.
I ran into this issue today and the root cause was ownership issues between two different queues. We had setup two queues, one to hold our message awaiting processing and one for messages that had errored out. The problem came with the logic of how the message was moved between queues.
If our processing failed, we would perform the following logic:
_errorQueue.AddMessage(msg);
_queue.DeleteMessage(msg);
The DeleteMessage would also return a (404) Not Found because the msg had been moved to the errorQueue. There were two solutions that I found to this issue:
1. Switch Logic
If you switch the logic than the msg will be deleted before being added to the errorQueue which will avoid the ownership swap.
_queue.DeleteMessage(msg);
_errorQueue.AddMessage(msg);
2. Insert Copy of Message
Solution #1 has the potential to lose the message if something happens between deletion and insertion (small chance but a chance nonetheless). The solution I went with inserted a copy of the msg with the same payload so it didn't run into this ownership issue because it was a different object.
_errorQueue.AddMessage(new CloudQueueMessage(msg.AsString));
_queue.DeleteMessage(msg);
Debugging Tip
One useful tip I encountered while debugging it making sure the exception your catching isn't the default Exception. Catch the StorageException instead to get access to Azure Storage related error information.
try
{
_queue.DeleteMessage(msg);
}
catch (StorageException ex) //use this instead of base Exception
{
var info = ex.RequestInformation; //has useful information
}
If can provide more information to help you debug your real issue.

Rebus - Send delayed message to another queue (Azure ServiceBus)

I have a website and and a webjob, where the website is a oneway client and the webjob is worker.
I use the Azure ServiceBus transport for the queue.
I get the following error:
InvalidOperationException: Cannot use ourselves as timeout manager
because we're a one-way client
when I try to send Bus.Defer from the website bus.
Since Azure Servicebus have built in support for timeoutmanager should not this work event from a oneway client?
The documentation on Bus.Defer says: Defers the delivery of the message by attaching a header to it and delivering it to the configured timeout manager endpoint
/// (defaults to be ourselves). When the time is right, the deferred message is returned to the address indicated by the header."
Could I fix this by setting the ReturnAddress like this:
headers.Add(Rebus.Messages.Headers.ReturnAddress, "webjob-worker");
Could I fix this by setting the ReturnAddress like this: headers.Add(Rebus.Messages.Headers.ReturnAddress, "webjob-worker");
Yes :)
The problem is this: When you await bus.Defer a message with Rebus, it defaults to return the message to the input queue of the sender.
When you're a one-way client, you don't have an input queue, and thus there is no way for you to receive the message after the timeout has elapsed.
Setting the return address fixes this, although I admit the solution does not exactly reek of elegance. A nicer API would be if Rebus had a Defer method on its routing API, which could be called like this:
var routingApi = bus.Advanced.Routing;
await routingApi.Defer(recipient, TimeSpan.FromSeconds(10), message);
but unfortunately it does not have that method at the moment.
To sum it up: Yes, setting the return address explicitly on the deferred message makes a one-way client capable of deferring messages.

Intermittent BridgeHandler & PublishSubscribeChannel call when gateways' reply channel is pub/sub

I'm seeing weird behaviour when sending data through my channels. I'm using SI gateway when sending a message to be processed. The gateway is setup as below
<integration:gateway id="rptPubGateway"
default-request-channel="rptPubInChannel"
default-reply-channel="rptOutputAvailableChannel"
default-reply-timeout="60000"
service-interface="xxxx.RptPubGateway" />
The reply channel is being set up as a publish/subscribe channel
<integration:publish-subscribe-channel id="rptOutputAvailableChannel" />
The last service that processes the message is being declared as below
<integration:service-activator input-channel="rptOutputAvailableChannel" ref="requestMessageHandler" method="rptIsDone" output-channel="nullChannel"/>
Now, the issue that i have is that while the code works fine most of the time, it fails sometimes. When everything works fine the last component processing my message is PublishSubsChannel
PublishSubscribeChannel - preSend on channel 'rptOutputAvailableChannel'
but when it fails the last component becomes BridgerHandler
BridgeHandler#e851a798' sending reply Message:
I should mention that there are no exceptions being thrown while processing my message. (after the failure I can always resend the same message and everything will work OK)
I'm not sure how that BridgerHandler gets created. From what I know this bridge gets created for pub/subs channels but then why I don't see it in the log when everything works fine ?
I'd appreciate any help
When you say "fails" what do you mean?
What are the other consumers on rptOutputAvailableChannel?
The BridgeHandler you see is an internal bridge to the message's replyChannel header, which is where the reply ultimately must go. When explicitly sending to rptOutputAvailableChannel, the bridge handler is always invoked to get the reply to the message's temporary reply channel.

Resources