Flex Multi Service call problem - apache-flex

I tried to call a service using a for loop and it seems that only the first service call seems to work. My guess is that once a service is called it needs to wait until result event until it can be called again. How can I workaround this?
Waiting for each service to complete before querying for another is too slow.
Ex.
callresponder id="test"
SomeService properly imported through Flash Builder 4
for (var i:int=0;i< pool.length;i++)
{
test.token = SomeService.getSomething(pool[i].someValue);
}
Only one would be successful. Help! I don't want to call after result event!

Problem: The problem is one call responder cannot be used by multiple service call.
Solution: Make more call responders....
var c:CallResponder;
before each iteration begins
c = new CallResponder();
c.addEventListener(ResultEvent.RESULT, resultHandler);
c.token = SomeService.whatEver(something);

Related

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.

LogicApps Web API making it Asynchronous

I had to write a Web API to insert data into custom on-premise DB and then call a stored procedure for LogicApps to use. The LogicApps' call timeouts when passing large amopnts of data. So I'm trying to use this solution I found here:
LogicAppsAsyncResponseSample
So I would basically put all my code into the doWork like this:
foreach (var record in records)
{
...
//Insert record
cmd.ExecuteNonQuery();
}
...
//Call SP
cmd.ExecuteNonQuery();
runningTasks[id] = true;
My question is should I make my code in doWork, asynchronous? Use Await as needed and ExecuteNonQueryAsync instead of ExecuteNonQuery and add AsynchronousProcessing to my connection string?
Alternatively, too I was actually considering writing this to be "Fire and Forget". Meaning I would start a thread in my API to call doWork as in the sample and return OK instead of Accepted right away. Then I wouldn't need to store thread statuses or have the chekcStatus method. This is OK for me since the API can send alerts if anything fails. The only advantage to the noted sample is I can eventually return something to LogicApps indicating success or not and show it in my LogicApps' log (one place to see all). Is "Fire and Forget" a sound practice?
FYI: the call to dowork in the sample is:
new Thread(() => doWork(id)).Start();

in Flex 3.2 Having troubles converting remote object result to specific object on client side in modules

in Flex 3.2 Having troubles converting remote object result to specific object on client side in modules.
For example I have VIPSAdmin module.
it has function
private function doResult(event:ResultEvent):void {
var data_:Array = ArrayUtil.toArray(event.result);
var result:ResultDTO = data_[0] as ResultDTO;
if(!result.isError()) {
trace(result.result);
vipsAdminDTO = result.result as VIPSAdmin;
compId= vipsAdminDTO.compId; // second time dying here
}
}
Function invoked when I get data from remote objet.
First time all great,when I unload this modeule and load it again:
data_[0] as ResultDTO;
Performs fine, but
vipsAdminDTO = result.result as VIPSAdmin;
vipsAdminDTO always null!
Even when
trace(result.result);
produces [object VIPSAdmin]
What a heck I missing here!? Looks like it just cannot do
result.result as VIPSAdmin;
even when trace and debug says it is instance of VIPSAdmin
I've figured out what is the problem, problem is that when I first instantiate something in module then in main app, somehow classes are not alined even that they are identical !
So solution is to make a fake instance in application class first, then if you use that same class to make an instance in module it will work!
I do it very simple in my main application class I just added:
VIPSAdmin;
This seems to create some sort of ghost instance, which I belie will be pickup by GC later, but will build tables of instances properly! Which solved my problem.
Not sure if this is appropriate solution ! but it sure works.

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.

Synchronous calls using RemoteObject

Is there a way to make synchronous calls using RemoteObject in Flex?
All IO in Flex is asynchronous. The typical pattern to deal with this is to use an AsyncResponder. For instance:
var t:AsyncToken = remoteObject.methodCall();
t.addResponder(new AsyncResponder(resultEvent, faultEvent));
think twice when u want it to be synchronous.
Do u know what synchronous mean? it will FREEZE your application until it receive data. Unless u are pretty sure that your remote calling can receive return value immediately (super fast network connection).
if your function call depends on each other, i would suggest you implement a state machine. e.g.
after 1st async call, your state becomes STATE_1, and your next function call will check on this state variable, to decide next move (ignore the current call or carry on).
my 2 cents.
If you want synchronous behavior, just add a wait after you make the call.
EDIT: I've added code for the chaining behavior I was talking about. Just replace the result handler each subsequent time you call the remoteObject.
...
remoteObject.function1(...);
...
private var resultHandler1(event:ResultEvent):void
{
...
remoteObject.removeEventListener(resultHandler1);
remoteObject.addEventListener(ResultEvent.RESULT, resultHandler2);
remoteObject.function2(...);
}
private var resultHandler2(event:ResultEvent):void
{
...
}
I achieved the same in two ways: First, as said above the use of state machines. It may get tricky at times. Second, the use of command queues - I think this is the best way to do it... but the downside is that the UI may not be very reflective in this time.
you should perhaps try and make one request with with all the data u want to be recieved synchronous and then make the different classes that need data listen to the correct data for that class.
ex:
// request
remoteobject.GetData();
// on received request
private function receivedData(evt:ResultEvent):void
{
for each (var resultobject:ResultObjectVO in evt.result)
{
var eventModel:Object;
var event:DataEvents = new DataEvents(resultobject.ResultType);
event.data = eventModel;
eventdispatcher.dispatchEvent(event);
}
}
Something like this. Hopes this helps.
No, why would you wish to do that anyway.
Flex makes things asynchronous so that the user isn't forced to sit and wait while data is coming back.
It would be a very poor user expereince if each time an app requested data the user had to wait on it coming back before anything else could happen.
from comment
No you don't need synchronus behaivour. If you're making say 2 calls and call 2 comes in before call 1, but 2 relies on the data inside 1 then you're left with either don't fire off event 2 till 1 comes back (this will slow down your app - much like synchronus events) or implement a way to check that event 1 has come back in event 2's handler (there are many ways you could do this).
If you're firing off many events then why not have a wrapper class of some description that tracks your events and doesn't do anything on the responses until all events are back.
You can use the AsyncToken to keep track of individual requests, so if you are firing of loads at once then you can find out exaclty whats come back and whats not.
You all are somehow mistaken or not using flex from adobe, if you send 2 calls to the server, no matter if each has an individual resquestObject the second one will ONLY be returned after the first one finish, even if the second one takes 1 milisecond to process. Just try the fibonnaci 1/40 example.
Maybe if you call a synchronous XMLHttpRequest calling JavaScript on Flex, you can do this.

Resources