How can you publish using the ConsumeContext<T>() when using IReceiveObserver - masstransit

When consuming faults implementing the IReceiveObserver, we are unable to publish via the ConsumeContext.Publish() method? The published messages aren't being received, what could be missing?
public Task ConsumeFault<T>(ConsumeContext<T> context, TimeSpan elapsed, string consumerType, Exception exception) where T : class
{
// called when the message is consumed but the consumer throws an exception
context.Publish(new {...}); //--> Doesn't publish the msg
}
To provide some context, we are firing off long running jobs and maintain a job dashboard to view their current status. Process flow is CreateJob->Send JobMessage-> JobConsumer receives and executes the task-> UpdateJob. All jobConsumer faults are being handled appropriately. In order to monitor Bus faults, we are looking to use the observers, so as to handle serialization/configuration errors etc. Aside from logging these faults, would also want to update the job state so that the dashboard would reflect the appropriate state. The IReceiveObserver receives the fault, however we would like to publish it to a central consumer to handle the updates as well. What am I missing?

For posterity was able to address this by registering an generic Fault consumer i.e IConsumer. As job context was in the message headers further actions were taken appropriately. Thank you Chris Patterson for the "MassTransit Commute - Consuming Fault Events" video!

Related

Prevent Kendo Scheduler events from inconsistent removal

We do have a kendo scheduler bound to a remote data source.
The transport configuration of this scheduler's data source is done using remote urls (for CRUD), and this works perfectly,
On the server side, we make a lot of checks. So if some requirements are missing, Create, Update or event Destroy operations wouldn't pass and user will be shown the meaningful error.
The problem we're facing now is like the following :
For the Destroy action, what kind of response should we send back (from the server) to the scheduler component (in the browser on the client side ) to prevent removal of events in the UI?
We've tried :
Sending back HTTP 500 status code
Putting an error field in the response and linking it to the schema.error configuration
But events are still removed from the UI, nevertheless the error event is fired. We even use this event to notify errors to end used.
Thank you.

Consequences of not awaiting

I have a .net webapi that has some code to send emails.
public async Task CheckOut(CheckOutData checkOutData){
...
...
...
//What are the risks if I remove the await
await SendEmail(checkOutData);
...
...
}
public async Task SendEmail(CheckOutData checkOutData)
{
try{
...
...
...
}
catch (exception ex){
//log Error
}
}
I have setup logging in the SendEmail code. My question is, if I remove the await, is it possible for the thread to be killed and the email not being sent if the execution completes before the SendEmail completes?
Am I safe if I remove the await? I am willing to accept that an exception will be swallowed, it will be logged.
The email will be sent unless the entire process stops.
Regarding threads, we can divide SendEmail to two parts:
SendEmail
// Code that will run on the calling thread. This is the code that will prepare the data and send it to the hardware.
// Code that will run on a thread-pool thread. This is the code that will run after the hardware will finish sending the message.
The first part of the method will hold the original thread so the thread will not be released before it will finish. The second part will run on a thread-pool thread so it doesn't matter if the original thread was released.
EDIT:
If you are hosting your application on IIS, the app domain maybe recycled so it's not advised to run code that last the request. It's described in this blog post https://blog.stephencleary.com/2012/12/returning-early-from-aspnet-requests.html
In the self-hosting case this feature doesn't exist (Application pool recycling with Selfhosting a ASP.NET application). So you can just run a long running process by using Task.Run
Long running task in ApiController (using WebAPI, self-hosted OWIN)
So in the self hosting case you can avoid the await. The part of your method that you won't wait for won't be killed. As in the Task.Run case described above.
Hope this helps

ActiveMQ OpenWire: How can I send the Java custom fields of an Exception thrown in BrokerFilter.send to the client/producer JVM side?

In order to create the functionality of listening on the client (producer/consumer) side to custom Exceptions thrown in broker plugins we're trying to relay a "custom correlation id" created upon message send, attached as property to the message and also attached to a JVM structure together with the callback to be called upon that exception being raised (a listener).
The things works, but the only issue we have is that we cannot send that custom correlation id back as part of the exception - it is a custom field, and by default OpenWire only transmits the stack and the message, is that correct?
What possibilities do you suggest to work this out, and be able to transmit back custom fields/values (other than encoding them in the message)?

How to include CorrelationId in microservice architecture?

I am creating a microservices architecture using ASP.NET Core web api. All the services are decoupled from each other, and may be deployed in different environments. Every service has its own logging. When requests flows through these services it could fail in any of the service, We need a way of tracing a series of events back to the source, even if it means traversing multiple services.
So to handle this issue, the service that originates the request creates a CorrelationId and pass it to the next service. The 2nd service pass it to 3rd service and so on. If exception occurs the corresponding service will log the exception message along with CorrelationId.
I wanted to know what would be a best place for the caller of the service to pass the correlationid?
Should the caller pass correlationid in HttpHeader or should it pass it as a part method parameter something like below
This is the service that is getting called
public class RequestDTO
{
public string CorrelationId {get;set;}
public string SomeOtherData {get;set;}
}
public Service2Controller:Controller
{
public Task<in> DoSomething(RequestDTO request)
{
// add the correlationid in current request Items collection
// So global exception handling can access it and log it
// along with the exception
HttpContext.Items.Add("CorrelationId", request.CorrelationId);
}
}
in the approach above if there is an exception before this method is invoked, the CorrelationId will not be available for global exception handler for logging.
Any suggestions? or alternate approach
The correlation identifier should not be something that you add yourself, some framework that sends the messages should do this. This way a developer can't forget it and it has a consistent behaviour all over the place.
Put a MessageId and CorrelationId in the headers of the message. On first message, both will be the same. On second message, CorrelationId is set to the MessageId of the previous one.
You could also set a unique ConversationId which never changes, to track all messages spawning from one originator. Useful when using pub/sub and/or calling back to the originator of a message.
Generally the best approach is to
let a library do it for you and
to follow standards where available
For example, see here and here how Application Insights does dependency & correlation tracking across different levels, using headers. And see this answer for a good description of it too.

What is the purpose of HandlerExtensions.ConnectHandle ConnectHandler<T>() method?

Xmldoc states:
Adds a message handler to the service bus for handling a specific type
of message
But it does not require endpoint name. How then does it work? I tried this method, but nothing happened.
Is there any possibility to add handlers dynamically, while bus is running?
By connecting a handler to the bus after it has been started, messages can be sent to the bus's address directly. This is particularly useful for things like responses to requests, which should not be published and are sent immediately back to the endpoint.
When using bus.ConnectHandler(context => {...}) to add a handler to the bus dynamically, no subscriptions or exchange bindings are created on the broker. It's only possible to receive messages which are directly sent to the endpoint.
When a message is sent from the bus, such as a request, the SourceAddress is added to the message header. If a request is sent, the ResponseAddress is also set. A fault address can also be specified if you want to use a non-dynamic endpoint to capture faults (such as a failed command that is not awaited, IE, fire and forget) so that faults can be triaged and handled appropriately by another persistent endpoint.

Resources