Chaining events/commands? - nservicebus

I have a feature I'm attempting to implement using NServiceBus but not sure the pattern to use here. (I'm fairly new to NServiceBus)
I'll try to explain where my uncertainty comes from:
User interaction triggers MVC controller to send a command to perform a domain operation. This command raises an event to notify others that this occurred.
A handler that subscribes to this event determines whether or not another domain operation should occur.
This is where I'm unclear as to the proper pattern to follow. At this point should the event handler:
just make the changes required?
send a new command to do it? If so, send it back to the originating service/process?
another option?
Part of me is wondering if I should be using an in-proc domain event to handle this, but I don't think the first command should have to wait on the second one before it returns. In fact it could happen much later. That is why I went the route of using the bus to handle it async. Also, an email will need to be generated once the second operation finishes. Should that be triggered from yet another event/command?
Any and all guidance appreciated.

If there is no need to wait for the second action then yes, it should be done asynchronously so the processing of the first command should publish an NServiceBus event. The handler for that event would (likely) be hosted in a separate endpoint which would then just do the work - no need to send another command there.

To add to Udi's answer, I would only turn around and send a command back to the originating service if the service at the originating endpoint is really the one that should be responsible for the behavior of that command. Otherwise, the service (endpoint) receiving the event should just do what it needs to do in response to the event (which sounds like your case).

Related

Nsb: Custom behavior after every handler

We want to log every occurrence of a handler running to completion and we're wondering what's the cleanest way to do it.
More specifically, when a Handler completes, we want to write some basic information like the type of the message that was processed etc, to a Db.
One way to do it is by creating and sending a new message (publishing an event) at the end of each handler.
But we're wondering if there is another way to do this without "polluting" the message handlers with those extra line of code :) For example, if after a Handler runs to completion, another method defined elsewhere would pick up execution and handle the logic of writing to the database.
Hope I made myself clear enough. Thanks
You could use the auditing pipeline and forward the audit messages to your audit queue and handle a copy of all messages there...
Here is some more info: https://docs.particular.net/nservicebus/operations/auditing?version=core_7.2
Does that make sense?

AXON framework synchronous response

I am new to AXON framework and are using it for our development. We have a requirement where command (command side) is created for the persisting data, for the same event is triggered which is consumed at query side. Now we need to have a response back to command side from query side which says if the record is persisted into database successfully (custom successful message) or if failed then the reason of the failure (custom exception message as response). Kindly help if there is any way to achieve such scenario.
Here command side and query side are 2 different micro-services and we are using Rabbit Mq for event driven technique.
Thanks in advance
I think that what you are asking is if there is a way for the command and event to be processed in a single transaction?
If you use a subscribing event processor, running in the same JVM, the event is processed synchronously and the whole transaction is rolled back in case of an exception in an event handler. This is not the case here, because you have loosely coupled separate services, which is good.
It's best practice for the aggregate with the command handler to have all the information available to decide whether or not the command can successfully be processed, and when an event is applied, this is a signal that it has happened, and the other services (the query side in this case) have to be informed. It's not good practice for a query module to overrule this ("you say it happened, I say it didn't"). If there is an error in the query side, you fix it, and replay the event.
If it really is an error in the event handler that the whole system must know about, that is really a separate event. You can apply such an event directly on the event bus and notify the whole system. Something like this:
#Autowired
private EventBus eventBus;
(...)
CatastrophicFailureEvent failureEvent = new CatastrophicFailureEvent("OH NO!");
eventBus.publish(GenericEventMessage.asEventMessage(failureEvent));
I think you might need to reconsider your architecture. Keep in mind that events should encapsulate the irreversible state changes of your system. These state changes should not be questioned after they have happened. Your query side should only need to care about projecting these valid state changes that your command side has decided on.
If you need to check whether a user already existed, you need to do this on the command side in your aggregate. The aggregate can keep a list of all the existing usernames and throw an exception if an invalid command is given. The command response (tip: using the sendAndWait() method on the CommandGateway returns a response) can then be used as the system to inform your user about the success/failure of its action.
The following flow might solve your problem, but keep in mind that the user will get a callback on the success of the action even though the query side might not have processed its result yet. This part is eventually consistent.
Command Side:
Request from frontend handled by a Controller class and creates an corresponding command
The above command is invoked and handled by a command handler which creates the corresponding event or throws an exception if the user already exists.
The invoker of the command is informed about the success of the command or the exception is handled and the error shown to the user.
The above event is published through rabbit mq event bus if the command was successful.
Query side:
The event that is published in the step 4 is consumed by the event handler in query side. No checks or validations should be necessary, since they were already handled on the command side.
#Mzzl
Series of activities
Command Side:
1. Request from frontend handled by a Controller class and creates an corresponding command
2. The above command is invoked and handled by a command handler which in return create corresponding event
3. The above event is then published through rabbit mq event bus.
Query Side:
4. The event that is published in the step 3 is consumed by the event handler in query side.
5. The event handler has the logic to perform db transaction (lets assume add a user). Once a user is added then a success message or failure message (lets assume user already available in the DB so could not create duplicate entry) should flow from query side to command side and eventually back to UI as a repsonse.
I'm not sure I've fully understand your issue (especially the microservice part :)),
but if your problem is related to having the query side up to date after the command execution, then you can have a look at this project.
In this example, you can see that he uses a SubscriptionQueryResult in conjunction with a QueryUpdateEmitter (see here)
Basically you will subscribe to query side changes before the command is issued, and you will block after the command execution until the query side send a notification when it is up to date.
This way you can avoid the eventual consistency.

Starting a Saga with Bus.SendLocal(IMessage) instead of Bus.Publish(IEvent)

I'm working on an application that requires regular polling of a 3rd party API. We've used NServiceBus heavily throughout this project and I decided to use the benefits of a Saga to help maintain the state of my poller.
In short, the Saga is used to maintain information required to ensure the polling is done correctly, and also to give us the simplicity of creating a timeout (after each poll) in order to ensure the next poll takes place, even if the service is stopped/compromised/blocked for whatever reason.
My first issue arose when I decided to initiate the Saga by having the service subscribe to its own events, and then publish one of those events when the service started (using IWantToRunWhenBusStartsAndStops). The problem with that was that the service would start and therefore publish the event, but it would happen before the subscriptions were created. The service would therefore not handle the event that was meant to kick off the whole Saga, unless I restarted it. Restarting the service in order to bypass this problem is not a solution that I want to even consider.
Since then, and with some playing around, I have discovered that using
Bus.SendLocal(new MyMessage()); (MyMessage implements IMessage)
will effectively start the Saga, without the need for subscription. The Saga is created in the database (I use NHibernate & MSSQL for persistence), and the timeouts are correctly created and function exactly as expected.
My only problem with this solution is that I am doing something that I cannot find any reference to in the NServiceBus documentation, and I'm concerned that I may be utilising a "feature" that may disappear in a future version, due to actually being an unintended side-effect.
In a nutshell - I'm starting a Saga by sending an IMessage using SendLocal. It works 100% and fixes all my issues, but is it "correct"?
Your solution is absolutely correct and there is no reason I can think of not to do that.

Nservicebus possible to publish an event when a message gets moved to error queue?

I have a saga that does a bulk import by creating a bunch of commands (It keeps track of the # of commands sent) then listens to an event indicating the task succeeded. I would also like to be notified when the command fails (moves into error queue).
I want to take advantage of nservicebus's retry functionality so I don't want to simply wrap it in a try catch, I really only want to publish this event when it is moving to the error queue.
Is it possible to create another end point that handles the generated commands but listens to the error queue? Or is there another better way to accomplish this?
You can take control over how the exceptions are handled using a custom fault handler

create WCF one-way (fire and forget) service out of XAMLX or how can a client call a service as one-way, if the operation is not defined one way

I am trying to create a XAMLX service that I can fire and forget.
But how can I do something like that with a XAMLX? I have no access to the Contract Interface to add the [OneWay] attribute.
I thought that if I did something like
and put the response before the rest of the activities, the service would return at that point but it didn't. It returns only after the whole workflow is completed.
IS it possible to make the service return at that point and than continue with the processing. the other activities would not affect the returned value of the service.
Is it possible to create a fire and forget XAMLX service
Can I somehow make the client fire a normal service as oneWay, if the previous 2 points are not possible?
If you want one-way processing your Receive activity should not have any corresponding SendReply activity.
The reason the response isn't send immediately is the way the workflow scheduler works internally where it waits for the workflow to go idle. Nothing much you can do about the scheduler but if you add a Delay below the SendResponse with a duration of 1 millisecond.
As Ladislav said, remove the SendResponse and you get a one way message.
Not quite sure what you want with fire and forget. If you start a workflow service it will keep on running even if you don't send any more WCF requests to it. Even if it is long running or does other async work. No problems there.