How to make Spring Webflow return one of more than 2 events - spring-webflow

I would like to return one of the possible 3 events from my action class. Most of the Spring Webflow events are binary as in they return success() / error() or yes() / no() types of events. I would like to return success() , error() and someThingElse() or some String events like approved, rejected, onHold
How would I do that?
Thank you
Chaitanya

Okay, I found the answer myself! Yet again.
Here it is:
I used Event org.springframework.webflow.action.AbstractAction.result(String eventId) to which one can pass any fancy event names as strings and SWF detects them. Voila.

Related

Fluxor: An effect which doesn't dispatch an action?

I'm using Fluxor to manage state in a Blazor wasm app.
I have the following effect which is triggered after getting a result from deleting an item:
[EffectMethod]
public Task HandleDeleteBudgetResultAction(DeleteBudgetResultAction action, IDispatcher dispatcher)
{
if (action.Success)
{
NavigationManager.NavigateTo("/budgets", false);
}
return Task.CompletedTask;
}
Essentially, if the delete was successful, navigate back to the list page. If it wasn't, do nothing as we need to remain on the detail page.
In this scenario I do not need to dispatch an action, but I have to include the dispatcher parameter, as demanded by the EffectMethod attribute. And since I have no async processes in this method, I am returning Task.CompletedTask.
This obviously feels wrong, so my question is: is this a limitation of Fluxor, or have I architected the flow incorrectly? As far as I'm aware, an effect doesn't have to dispatch an action.
I was thinking I might need to move my navigation state into the store, but I think I'll just come across the same problem again because I'll still need to call NavigationManager from somewhere.
Any help or better solutions appreciated :)
It is a limitation of Fluxor. You can dispatch a GoAction instead of injecting the NavigationManager, as long as you have called UseRouting on the Fluxor options.
builder.Services.AddFluxor(options => options
.UseRouting()
.ScanAssemblies(typeof(Program).Assembly)

How to make command to wait until all events triggered against it are completed successfully

I have came across a requirement where i want axon to wait untill all events in the eventbus fired against a particular Command finishes their execution. I will the brief the scenario:
I have a RestController which fires below command to create an application entity:
#RestController
class myController{
#PostMapping("/create")
#ResponseBody
public String create(
org.axonframework.commandhandling.gateway.CommandGateway.sendAndWait(new CreateApplicationCommand());
System.out.println(“in myController:: after sending CreateApplicationCommand”);
}
}
This command is being handled in the Aggregate, The Aggregate class is annotated with org.axonframework.spring.stereotype.Aggregate:
#Aggregate
class MyAggregate{
#CommandHandler //org.axonframework.commandhandling.CommandHandler
private MyAggregate(CreateApplicationCommand command) {
org.axonframework.modelling.command.AggregateLifecycle.apply(new AppCreatedEvent());
System.out.println(“in MyAggregate:: after firing AppCreatedEvent”);
}
#EventSourcingHandler //org.axonframework.eventsourcing.EventSourcingHandler
private void on(AppCreatedEvent appCreatedEvent) {
// Updates the state of the aggregate
this.id = appCreatedEvent.getId();
this.name = appCreatedEvent.getName();
System.out.println(“in MyAggregate:: after updating state”);
}
}
The AppCreatedEvent is handled at 2 places:
In the Aggregate itself, as we can see above.
In the projection class as below:
#EventHandler //org.axonframework.eventhandling.EventHandler
void on(AppCreatedEvent appCreatedEvent){
// persists into database
System.out.println(“in Projection:: after saving into database”);
}
The problem here is after catching the event at first place(i.e., inside aggregate) the call gets returned to myController.
i.e. The output here is:
in MyAggregate:: after firing AppCreatedEvent
in MyAggregate:: after updating state
in myController:: after sending CreateApplicationCommand
in Projection:: after saving into database
The output which i want is:
in MyAggregate:: after firing AppCreatedEvent
in MyAggregate:: after updating state
in Projection:: after saving into database
in myController:: after sending CreateApplicationCommand
In simple words, i want axon to wait untill all events triggered against a particular command are executed completely and then return to the class which triggered the command.
After searching on the forum i got to know that all sendAndWait does is wait until the handling of the command and publication of the events is finalized, and then i tired with Reactor Extension as well using below but got same results: org.axonframework.extensions.reactor.commandhandling.gateway.ReactorCommandGateway.send(new CreateApplicationCommand()).block();
Can someone please help me out.
Thanks in advance.
What would be best in your situation, #rohit, is to embrace the fact you are using an eventually consistent solution here. Thus, Command Handling is entirely separate from Event Handling, making the Query Models you create eventually consistent with the Command Model (your aggregates). Therefore, you wouldn't necessarily wait for the events exactly but react when the Query Model is present.
Embracing this comes down to building your application such that "yeah, I know my response might not be up to date now, but it might be somewhere in the near future." It is thus recommended to subscribe to the result you are interested in after or before the fact you have dispatched a command.
For example, you could see this as using WebSockets with the STOMP protocol, or you could tap into Project Reactor and use the Flux result type to receive the results as they go.
From your description, I assume you or your business have decided that the UI component should react in the (old-fashioned) synchronous way. There's nothing wrong with that, but it will bite your *ss when it comes to using something inherently eventually consistent like CQRS. You can, however, spoof the fact you are synchronous in your front-end, if you will.
To achieve this, I would recommend using Axon's Subscription Query to subscribe to the query model you know will be updated by the command you will send.
In pseudo-code, that would look a little bit like this:
public Result mySynchronousCall(String identifier) {
// Subscribe to the updates to come
SubscriptionQueryResult<Result> result = QueryGateway.subscriptionQuery(...);
// Issue command to update
CommandGateway.send(...);
// Wait on the Flux for the first result, and then close it
return result.updates()
.next()
.map(...)
.timeout(...)
.doFinally(it -> result.close());
}
You could see this being done in this sample WebFluxRest class, by the way.
Note that you are essentially closing the door to the front-end to tap into the asynchronous goodness by doing this. It'll work and allow you to wait for the result to be there as soon as it is there, but you'll lose some flexibility.

ASP.NET Async Tasks - how to use WebClient.DownloadStringAsync with Page.RegisterAsyncTask

A common task I have to do for a site I work on is the following:
Download data from some third-party API
Process the data in some fashion
Display the results on the page
I was initially using WebClient.DownloadStringAsync and doing my processing on the result. However I was finding that DownloadStringAsync was not respecting the AsyncTimeout parameter, which I sort of expected once I did a little reading about how this works.
I ended up adapting the code from the example on how to use PageAsyncTask to use DownloadString() there - please note, it's the synchronous version. This is probably okay, because the task is now asynchronous. The tasks now properly time out and I can get the data by PreRender() time - and I can easily genericize this and put it on any page I need this functionality.
However I'm just worried it's not 'clean'. The page isn't notified when the task is done like the DownloadStringAsync method would do - I just have to scoop the results (stored in a field in the class) up at the end in my PreRender event.
Is there any way to get the Webclient's Async methods to work with RegisterPageTask, or is a helper class the best I can do?
Notes: No MVC - this is vanilla asp.net 4.0.
If you want an event handler on your Page called when the async task completes, you need only hook one up. To expand on the MSDN "how to" article you linked:
Modify the "SlowTask" class to include an event, like - public event EventHandler Finished;
Call that EventHandler in the "OnEnd" method, like - if (Finished != null)
{
Finished(this, EventArgs.Empty);
}
Register an event handler in your page for SlowTask.Finished, like - mytask.Finished += new EventHandler(mytask_Finished);
Regarding ExecuteRegisteredAsyncTasks() being a blocking call, that's based only on my experience. It's not documented explicitly as such in the MSDN - http://msdn.microsoft.com/en-us/library/system.web.ui.page.executeregisteredasynctasks.aspx
That said, it wouldn't be all that practical for it be anything BUT a blocking call, given that it doesn't return a WaitHandle or similar. If it didn't block the pipeline, the Page would render and be returned to the client before the async task(s) completed, making it a little difficult to get the results of the task back to the client.

Actionscript 3: How to do multiple async webservice call requests

I am using Flex and Actionscript 3, along with Webservices, rpc and a callResponder. I want to be able to, for example, say:
loadData1(); // Loads webservice data 1
loadData2(); // Loads webservice data 2
loadData3(); // Loads webservice data 3
However, Actionscript 3 works with async events, so for every call you need to wait for the ResultEvent to trigger when it is done. So, I might want to do the next request every time an event is done. However, I am afraid that threading issues might arise, and some events might not happen at all. I don't think I'm doing a good job of explaining, so I will try to show some code:
private var service:Service1;
var cp:CallResponder = new CallResponder();
public function Webservice()
{
cp.addEventListener(ResultEvent.RESULT, webcalldone);
service = new Service1();
}
public function doWebserviceCall()
{
// Check if already doing call, otherwise do this:
cp.token = service.WebserviceTest_1("test");
}
protected function webcalldone(event:ResultEvent):void
{
// Get the result
var result:String = cp.lastResult as String;
// Check if other calls need to be done, do those
}
Now, I could ofcourse save the actions in an arraylist, but whose to say that the addToArrayList and the check if other calls are available do not mess eachother up, or just miss each other, thereby halting execution? Is there something like a volatile Arraylist? Or is there a completely different, but better solution for this problem?
Use an AsyncToken to keep track of which call the returned data was for http://flexdiary.blogspot.com/2008/11/more-thoughts-on-remoting.html
When I want to store data in an async manor I put it in an array and make a function that will "pop" the element as I send it off.
This function will be called on complete and on error events.
Yes I know there could be an issue with the server and data lost but oh well. That can also be handled
Events will always fire however, it may not be a complete event that gets fired but could be an error event.
Once the array is empty the function is done.

MVVM Light Messenger executing multiple times

I am using MVVM Light and am using Messages to communicate between ViewModels to let a ViewModel know when it is ok to execute something. My problem is that I register for a message and then it receives it multiple times. so to keep from my program executing something more than once I have to create boolean flags to see if it has already been recieved. Any idea why it does this and how I can stop it?
Make sure you unregister your message handlers once you do not need them anymore. The Messenger keeps a reference to the registered methods and this prevents them from being garbage collected.
Therefore, for ViewModels: make sure that you call Cleanup once you done (or implement IDisposable and call Cleanup from there).
For Views (Controls, Windows, or similar) call Messenger.Unregister in an event that occurs on the teardown of the view, e.g. the Unloaded event.
This is a known behaviour of the MVVM and has been discussed in several places.
Very old question but I solved the problem by doing this:
static bool isRegistered = false;
and then, in the constructor:
if( !isRegistered )
{
Messenger.Default.Register<MyMessage>(this, OnMessageReceived);
isRegisterd = true;
}
I have seen this issue before. It had to do with the Messenger.Default.Register being called more than once. The MVVMLight Messenger class will register the same item 'x' number of times. This is why when you call the Send you get it many times.
Anyone know how to prevent MVVMLight from registering multiple times?
really old but thought I would answer just in case somebody needs it. I was fairly new to silverlight at the time and the issue ended up being a memory leak as the viewModel, which had multiple instances, was still in memory.
As other contributors mentioned, the same message is being registered multiple times. I have noticed this behavior taking place while navigating to View X then navigating back to View Z where the message is registered in the constructor of the Z ViewModel. One solution is to set the NavigationCacheMode property to Required
<Page
........
........
NavigationCacheMode="Required">

Resources