In Signalr, is there any support for having events instead of callbacks.
Let me explain before you grab your pitchforks.
In following with the first example here
Clients.All.addContosoChatMessageToPage(name, message);
Wouldn't call a hub proxy's addContosoChatMessageToPage(name, message), but would dispatch a addContosoChatMessageToPage event with some extra information. (not asking that it be the same api call exactly)
The reason I'm asking all of this is because
This works much better alongside functional reactive programming frameworks like ELM and bacon.js
I don't want to do this myself and essentially create my own sub-framework. Of course I could always do Clients.All.CreateEvent(name,params...) where I'm continually calling back my method to do this event creation
I actually think events work better in some scenarios for separation of concerns.
Am I crazy? does something like this exist?
This is already supported. If you don't want to do the dispatching yourself and you know the name of the "event" or "method" at runtime you can do this:
IClientProxy proxy = Clients.All;
proxy.Invoke(name, args);
This lets you write code where you may not know the name of the event you're trying to callback on the client at compile time.
Related
We are using MediatR to implement a "Pipeline" for our dotnet core WebAPI backend, trying to follow the CQRS principle.
I can't decide if I should try to implement a IPipelineBehavior chain, or if it is better to construct a new Request and call MediatR.Send from within my Handler method (for the request).
The scenario is essentially this:
User requests an action to be executed, i.e. Delete something
We have to check if that something is being used by someone else
We have to mark that something as deleted in the database
We have to actually delete the files from the file system.
Option 1 is what we have now: A DeleteRequest which is handled by one class, wherein the Handler checks if it is being used, marks it as deleted, and then sends a new TaskStartRequest with the parameters to Delete.
Option 2 is what I'm considering: A DeleteRequest which implements the marker interfaces IRequireCheck, IStartTask, with a pipeline which runs:
IPipelineBehavior<IRequireCheck> first to check if the something is being used,
IPipelineBehavior<DeleteRequest> to mark the something as deleted in database and
IPipelineBehavior<IStartTask> to start the Task.
I haven't fully figured out what Option 2 would look like, but this is the general idea.
I guess I'm mainly wondering if it is code smell to call MediatR.Send(TRequest2) within a Handler for a TRequest1.
If those are the options you're set on going with - I say Option 2. Sending requests from inside existing Mediatr handlers can be seen as a code smell. You're hiding side effects and breaking the Single Responsibility Principle. You're also coupling your requests together and you should try to avoid situations where you can't send one type of request before another.
However, I think there might be an alternative. If a delete request can't happen without the validation and marking beforehand you may be able to leverage a preprocessor (example here) for your TaskStartRequest. That way you can have a single request that does everything you need. This even mirrors your pipeline example by simply leveraging the existing Mediatr patterns.
Is there any need to break the tasks into multiple Handlers? Maybe I am missing the point in mediatr. Wouldn't this suffice?
public async Task<Result<IFailure,ISuccess>> Handle(DeleteRequest request)
{
var thing = await this.repo.GetById(request.Id);
if (thing.IsBeignUsed())
{
return Failure.BeignUsed();
}
var deleted = await this.repo.Delete(request.Id);
return deleted ? new Success(request.Id) : Failure.DbError();
}
I'm learning SignalR using the .Net client (not javascript), and was hoping for some clarification on how to invoke hub proxy methods in a synchronous or asynchronous manner.
Method with no return value
So far I've been doing something like this:-
myHubProxy.Invoke("DoSomething");
I've found this to be asynchronous, which is fine as it's effectively "fire-and-forget" and doesn't need to wait for a return value. A couple of questions though:-
Are there any implications with wrapping the Invoke in a try..catch block, particularly with it being asynchronous? I might want to know if the call failed.
Are there any scenarios where you would want to call a method that doesn't return a value synchronously? I've seen the .Wait() method mentioned, but I can't think why you would want to do this.
Method with return value
So far I've been using the Result property, e.g.:-
var returnValue = myHubProxy.Invoke<string>("DoSomething").Result;
Console.WriteLine(returnValue);
I'm assuming this works synchronously - after all, it couldn't proceed to the next line until a result had been returned. But how do I invoke such a method asynchronously? Is it possible to specify a callback method, or should I really be using async/await these days (something I confess to still not learning about)?
If you want to write asynchronous code, then you should use async/await. I have an intro on my blog with a number of followup resources at the end.
When you start an asynchronous operation (e.g., Invoke), then you get a task back. The Task type is used for asynchronous operations without a return value, and Task<T> is used for asynchronous operations with a return value. These task types can indicate to your code when the operation completes and whether it completed successfully or with error.
Although you can use Task.Wait and Task<T>.Result, I don't recommend them. For one, they wrap any exceptions in an AggregateException, which make your error handling code more cumbersome. It's far easier to use await, which does not do this wrapping. Similarly, you can register a callback using ContinueWith, but I don't recommend it; you need to understand a lot about task schedulers and whatnot to use it correctly. It's far easier to use await, which does the (most likely) correct thing by default.
The .Result property returns a async Task, so the server requests is still performed async.
There is not reason to hold up a thread for the duration of the call thats why you use async.
If you fire the call on the GUI thread its even more important todo it async because otherwise the GUI will not respond while the call is done
1) Yuo need to use the await keyword if you want try catch blocks to actually catch server faults. Like
try
{
var foo = await proxy.Invoke<string>("Bar");
}
catch (Exception ex)
{
//act on error
}
2) I think you ment to ask if its any reason to call it async? And yes like I said, you do not want to block any threads while the request is being made
I have a need to validate a field against our database to verify unique-ness. The problem I seem to be having is that the validators doValidation() exits before we've heard back from database.
How can I have the validator wait to return its payload until after we've heard from the DB?
Or perhaps a better question might be (since I think the first question is impossible), how can I set this up differently, so that I don't need to wait, or so that the wait doesn't cause the validation to automaticallly return valid?
If you're using a remote object, you can specify the method call inside your remote declaration and assign a function to the result call. The result call only runs once the remote server returns something, so it won't be run before your validation.
Do your validation call in said result function call (which you will have to create) and you should be good. Your code should go something like this:
<s:RemoteObject id="employeeService"
destination="ColdFusion"
source="f4iaw100.remoteData.employeeData"
endpoint="http://adobetes.com/flex2gateway/"
result="employeeService_resultHandler(event)"/>
**<s:method name="dataCheckCall" result="dataCheckResult(event)"/>**
<s:RemoteObject />
And in your script:
function protected dataCheckResult(event:ResultEvent):void {
**doValidate();**
}
Edit: As soon as you call "dataCheckCall" the method will start running. If, for whatever reason, you want to call this WITHIN your validator, you can do so, and then dataCheckResult will run whenever it returns with it's payload (pretend doValidate is called elsewhere). I've left a message below as well.
You are trying to fit an asynchronous process (fetching data from a DB) into a synchronous process (checking all the validators in turn).
This won't work...
You'll need to either roll your own validator framework, or use a different method of determining the legality of your controls.
P.S. The MX validators are rubbish anyway!
What I've managed to do, seems to work, mostly. I don't like it, but it at least performs the validation against the remote source.
What I've done, then, is to use an 'keyUp' event handler to spin off the database lookup portion. In the meanwhile, I set up a string variable to act as some kind of a Flag, which'll be marked as 'processing'. When the response event fires, I'll examine its contents, and either clear the flag, or set it to some kind of other error.
Then, I have created a new 'EmptyStringValidator' will check the contents of this flag, and do its job accordingly.
Its indirect, but, so far, seems to work.
I have a function that loads a user object from a web service asynchronously.
I wrap this function call in another function and make it synchronous.
For example:
private function getUser():User{
var newUser:User;
var f:UserFactory = new UserFactory();
f.GetCurrent(function(u:User):void{
newUser = u;
});
return newUser;
}
UserFactory.GetCurrent looks like this:
public function GetCurrent(callback:Function):void{ }
But my understanding is there is no guarantee that when this function gets called, newUser will actually be the new user??
How do you accomplish this type of return function in Flex?
This way madness lies.
Seriously, you're better off not trying to force an asynchronous call into some kind of synchronous architecture. Learn how the event handling system works in your favour and add a handler for the result event. In fact, here's the advice straight from the flexcoders FAQ :
Q: How do I make synchronous data calls?
A: You CANNOT do synchronous calls. You MUST use the result event. No,
you can't use a loop, or setInterval or even callLater. This paradigm is
quite aggravating at first. Take a deep breath, surrender to the
inevitable, resistance is futile.
There is a generic way to handle the asynchronous nature of data service
calls called ACT (Asynchronous Call Token). Search for this in
Developing Flex Apps doc for a full description.
See my answer here:
DDD and Asynchronous Repositories
Flex and Flash Remoting is inherently asynchronous so fighting against that paradigm is going to give you a ton of trouble. Our service delegates return AsyncToken from every method and we've never had a problem with it.
If you want to ensure that the application doesn't render a new view or perform some other logic until the result/fault comes back, you could do the following:
Attach an event listener for a custom event that will invoke your "post result/fault code"
Make the async call
Handle the result/fault
Dispatch the custom event to trigger your listener from #1
Bear in mind this going to lead to a lot of annoying boilterplate code every time you make an async call. I would consider very carefully whether you really need a synchronous execution path.
You can't convert async call into sync one without something like "sleep()" function and as far as I know it is missing in AS3. And yes, it is not guaranteed that newUser would contain user name before return statement.
The AS3 port of the PureMVC framework has mechanisms for implementing synchronous operations in a Model-View-Controller context. It doesn't try to synchronize asynchronous calls, but it lets you add a synchronous application pattern for controlling them.
Here's an example implementation: PureMVC AS3 Sequential Demo.
In this example, five subcommands are run sequentially, together composing a whole command. In your example, you would implement getUser() as a command, which would call commandComplete() in the getURL() (or whatever) callback. This means the next command would be certain that the getUser() operation is finished.
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.