I am using Google AppEngine, in conjunction with PyAMF to provide RemoteObject support. In my Flex code I make several RemoteObject method calls at once which tends to batch the AMF Messages into a single HTTP request.
Most of the time this is fine but AppEngine applies some strict per request limits (in this case I am hitting a DeadlineExceededError - max 30 seconds). A number of service methods are expected to take upwards of 10 seconds and if these are batched by the RemoteObject into 1 HTTP .. you see where this is going.
Now you could say refactor your service calls and that is also going on but not really the question being asked here. Is there a way to prevent Flex RemoteObject from batching AMF requests for situations like this?
I have done a fair amount of Googling on the subject and come up with bupkis. It seems to me that I would need to implement a custom version of mx.messaging.channels.AMFChannel or something of that nature, which seems waay too hardcore for a feature like this ..
Anyone have any pointers/insight?
Check out the concurrency property on RemoteObject.
The batching of AMF requests into HTTP happens at the NetConnection level. So unfortunately the best way to stop AMF requests from batching is to implement a custom version of the mx.messaging.channels.AMFChannel. However this is quite easy to do, and probably easier that queuing requests and calling them later.
Instead of using the default AMFChannel use the following instead:
package services
{
import flash.events.AsyncErrorEvent;
import flash.events.IOErrorEvent;
import flash.events.NetStatusEvent;
import flash.events.SecurityErrorEvent;
import flash.net.NetConnection;
import mx.messaging.MessageResponder;
import mx.messaging.channels.AMFChannel;
public class NonBatchingAMFChannel extends mx.messaging.channels.AMFChannel
{
public function NonBatchingAMFChannel(id:String = null, uri:String = null)
{
super(id, uri);
}
override protected function internalSend(msgResp:MessageResponder):void
{
// AMFChannel internalSend
super.internalSend(msgResp);
// Reset the net connection.
_nc = new NetConnection();
_nc.addEventListener(NetStatusEvent.NET_STATUS, statusHandler);
_nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
_nc.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
_nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
_nc.connect(this.url);
}
}
}
The magic happens by overriding the internalSend method. After running the super internalSend method (which queues the message responder), we will reset the NetConnection and all of its event handlers. This gets a new NetConnection ready for the next remoting message.
Note:
It's important to note that this is a custom non batching AMFChannel, if you want send AMF messages securely you'll need to copy this class and extend the mx.messaging.channels.SecureAMFChannel class.
Credit:
Credit to Nick Joyce who answered his question here on a different forum.
you can create a pool of connections, and create another another class that triggers the connections. Your application does not make the connections, only feeds the pool.
Well, one way is apparently to roll your own AMFChannel that doesn't use NetConnection... I haven't tried it so I don't know how well it works.
http://blogs.adobe.com/pfarland/2008/06/using_amf_with_flashneturlload.html
I think what njoyce like to do is to prevent AMF batching. This ie. is good for multiple small calls but if you have very server-intensive calls you AMF batching should be prevented. Why?
one AMF call => one thread on server side
multiple AMF calls => all requests get handled through multiple threads
Pseudo Code:
private static var _collectionFillIndex:int;
private static var _collectionsToFill:Array = [];
public function doFillCollections():void {
_collectionFillIndex = _collectionsToFill.length;
Application.application.addEventListener( Event.ENTER_FRAME, onFrameEventHandler );
}
private function onFrameEventHandler( event:Event ):void {
--_collectionFillIndex;
if( _collectionFillIndex < 0 ) {
Application.application.removeEventListener( Event.ENTER_FRAME, onFrameEventHandler );
return;
}
_collectionsToFill[ _managerFillIndex ].fill();
}
Related
I'm just getting started with SignalR and I'm wondering if it's a good tool for the task I'm working on.
In short, I have objects with properties that change over time. A timer job runs every once in a while to update these properties. For the sake of explanation, let's say I have MilkJugs with a property "isExpired" that changes once a certain DateTime is hit.
When my timerjob hits a MilkJug and flips it to isExpired = true, I want all clients to get a notification instantly. If a client is looking at seven MilkJugs in Chrome, I want them to see all seven MilkJugs turn yellow (or something like that).
Could I use signalR to "broadcast" these notifications to the clients from the timerJob? I just ran through the chat example they have up and it seems super simple to get working... I think I could do something like this serverside:
public class ChatHub : Hub
{
public void Send(List<MilkJugUpdate> updates)
{
// Call the broadcastMessage method to update milkJugs.
Clients.All.broadcastMessage(updates);
}
}
And then clientside just iterate over the serialized array, updating the appropriate fields in my JS viewModels.
Does this sound about right?
You have got the basic idea there. However there are probably some improvements you could make.
Here I assume you send the message every time you run the timer job. This isn't necessary. You only really need to send a message to the clients if something changes.
Firstly you could handle the onconnected event, and send the current state of the milk jugs.
Now when you run the timer job, you only need to call send if something has changed. Then you send the message to the clients, telling them what has changed. On the clients side, the function handles the change something like the following
Server
public class ChatHub : Hub
{
public override Task OnConnected()
{
//some code here to fetch current state of jugs.
return base.OnConnected();
}
public void JugExpired(MilkJugUpdate update)
{
// Call the broadcastMessage method to update milkJugs.
Clients.All.updateJug(update);
}
}
Client
ChatHub.client.updateJug = function(update) {
// code to update jug here
}
This saves you sending messages to the client if nothing has changed.
Similarly as pointed out in another answer, you can call the client method directly from your timer job, but again, I would only recommend sending updates, rather than the entire state every time.
Absolutely, ShootR does this already (HTML5 multiplayer game). This is also done in the Stock Ticker Sample on nuget.
Ultimately, you can grab the hub context outside of the hub and use it to send messages:
public void MyTimerFunction(object state)
{
GlobalHost.ConnectionManager.GetHubContext<ChatHub>().Clients.All.broadcastMessage(updates);
}
I have a web site which makes frequent requests to an external web service, and I'd like these calls to be async and parallel to avoid blocking and to speed up the site a bit. Basically, I have 8 widgets, each of which has to make its own web call(s).
For some reason, only the first 3 or so of them truly load async, and then the threads don't free up in time, and the rest of the widgets load sequencially. If i could get 3 of them to load in parallel, then 3 more in parallel, then 2 more in parallel, i'd be happy. So the issue is really that the threads aren't freeing up in time.
I'm guessing the answer has to do with some IIS configuration. I'm testing on a non-server OS, so maybe that's part of it.
Edit for #jon skeet:
I'm using reflection to invoke the web calls like this:
output = methodInfo.Invoke(webservice, parameters);
The widget actions (which eventually call the web service) are called via a jquery $.each() loop and the .load function (maybe this causes a bottleneck?). The widget actions are set up as async methods in an async controller.
Here is the code for one of the async methods (they are all set up like this):
public void MarketTradeWidgetAsync()
{
AsyncManager.OutstandingOperations.Increment();
//a bunch of market trade logic
//this eventually calls the web service
PlanUISetting uiSettingMarketQuotesConfig = WebSettingsProviderManager.Provider.GetMarketQuotes(System.Configuration.ConfigurationManager.AppSettings["Theme"], SessionValues<String>.GlobalPlanID, SessionValues<String>.ParticipantID, "MARKETQUOTES");
AsyncManager.OutstandingOperations.Decrement();
}
public ActionResult MarketTradeWidgetCompleted(MarketTradeTool markettradetool)
{
if (Session.IsNewSession)
return PartialView("../Error/AjaxSessionExpired");
else
{
ViewData["MarketData"] = markettradetool;
return PartialView(markettradetool);
}
}
And, like I said, these methods are called via jquery. My thinking is that since the action methods are async, they should give control back to the jquery after they get called, right?
SessionState = "readonly" for the page at hand fixed this issue. Evidently session locking was the issue.
I was wondering how TransactionScope class works to keep the transaction between different method calls (without the need to pass it as a parameter) and I came to this doubt. I've got two considerations about this question:
1
Looking into TransactionScope's implementation through Telerik JustDecompile, I've found that the current transaction is stored in a ThreadStatic member of the System.Transactions.ContextData class (code below).
internal class ContextData
{
internal TransactionScope CurrentScope;
internal Transaction CurrentTransaction;
internal DefaultComContextState DefaultComContextState;
[ThreadStatic]
private static ContextData staticData;
internal WeakReference WeakDefaultComContext;
internal static ContextData CurrentData
{
get
{
ContextData contextDatum = ContextData.staticData;
if (contextDatum == null)
{
contextDatum = new ContextData();
ContextData.staticData = contextDatum;
}
return contextDatum;
}
}
public ContextData()
{
}
}
The CurrentData property is called by TransactionScope's PushScope() method, and the last one is used by most of the TransactionScope constructors.
private void PushScope()
{
if (!this.interopModeSpecified)
{
this.interopOption = Transaction.InteropMode(this.savedCurrentScope);
}
this.SetCurrent(this.expectedCurrent);
this.threadContextData.CurrentScope = this;
}
public TransactionScope(TransactionScopeOption scopeOption)
{
// ...
this.PushScope();
// ...
}
Ok, I guess I've found how they do that.
2
I've read about how bad is to use ThreadStatic members to store objects within ASP.NET (http://www.hanselman.com/blog/ATaleOfTwoTechniquesTheThreadStaticAttributeAndSystemWebHttpContextCurrentItems.aspx) due the ASP.NET thread switching that might occur, so this data can be lost among the worker threads.
So, it looks like TransactionScope should not work with ASP.NET, right? But as far I have used it on my web applications, I don't remember any problem that I've run into about transaction data being lost.
My question here is "what's the TransactionScope's trick to deal with ASP.NET's thread switching?".
Did I make a superficial analysis on how TransactionScope stores its transaction objects? Or TransactionScope class wasn't made to work with ASP.NET, and I can be considered a lucky guy that never had any pain about it?
Could anyone who knows the "very deep buried secrets" of .NET explain that for me?
Thanks
I believe ASP.NET thread switching happens only in specific situations (involving asych IO operations) and early in the request life cycle. Typically, once the control is passed to the actual http handler (for example, Page), thread does not get switched. I believe that in most of situation, transaction scope will get initialized only after that (after page_init/load) and should not be an issue.
Here are few links that might interest you:
http://piers7.blogspot.com/2005/11/threadstatic-callcontext-and_02.html
http://piers7.blogspot.com/2005/12/log4net-context-problems-with-aspnet.html
What would be a clever way to make a 'please wait' control for a Flex application for long running operations like calling a webservice.
I am not asking about the graphical portion of it - just the 'controller' part. How should I trigger it and hide it. I am planning to make just a simple canvas with text in.
For instance :
can I somehow intercept all web service calls - and not have to activate it for every web service
how should i add it to my canvas. should it be added to 'stage' as a top level component?
should it have a 'cancel' button to cancel the web service request if it takes too long. that sounds kind of complicated because I'm not even sure if I can terminate a running async web request?
FYI: This is for a reporting application so long running queries are to be expected
One way I have done it in the past is to have a global integer and increment / decrement the value based on the web services running. When the counter was 0, I would hide the loading text, when it was greater than 0, I would display the loading text. Here is a simplified version of it:
<mx:Application>
<mx:Script>
[Bindable]public var ws_count:int = 0;
</mx:Script>
<mx:Label text = "loading..." visible="{ws_count > 0}" />
</mx:Application>
I then had a little helper class to control the global counter:
package ws {
import mx.core.Application;
public class WSCounter {
public static function sent():void {
Application.application.ws_count += 1;
}
public static function receive():void {
Application.application.ws_count -= 1;
}
}
}
Then all that needs to be done is to call the helper function when a web service is called...e.g:
import ws.WSCounter;
import mx.rpc.http.HTTPService;
var srv:HTTPService = new HTTPService();
srv.url = "http://localhost/service.py";
srv.addEventListener(ResultEvent.RESULT,function(event:ResultEvent):void {
WSCounter.receive();
});
srv.send();
WSCounter.sent();
I always have thought there was a better way to do this, like you said have some type of hook to detect if a service is running...I'm looking forward to other responses in this post...
If you are using a framework like Cairngorm or similar that implements MVC, the straightforward approach is to update a "global" variable (via a Singleton object) thats bound to UI Component's (ie. titleWindow under main mxml or whatever) visible attribute. the variable will be updated to true during execute() and false when it reaches result or fault callback methods.
You can add a "cancel" button that resets the variable to "false" but it doesnt mean the server will stop the async call. i dont know how to stop it and prevent it from returning a data from a cancelled method call. taking a quick look at the ASDoc, remoteobject does have a disconnect() method that discards all the pending request responders. im not sure if its the elegant/right way to do it
if you do not want to set it for every web service call, you might wanna use a custom event chaining (see http://www.herrodius.com/blog/80 for ideas) so that you only have to set it once if you are calling single or multiple services.
I've been utilizing the command pattern in my Flex projects, with asynchronous callback routes required between:
whoever instantiated a given command object and the command object,
the command object and the "data access" object (i.e. someone who handles the remote procedure calls over the network to the servers) that the command object calls.
Each of these two callback routes has to be able to be a one-to-one relationship. This is due to the fact that I might have several instances of a given command class running the exact same job at the same time but with slightly different parameters, and I don't want their callbacks getting mixed up. Using events, the default way of handling asynchronicity in AS3, is thus pretty much out since they're inherently based on one-to-many relationships.
Currently I have done this using callback function references with specific kinds of signatures, but I was wondering if someone knew of a better (or an alternative) way?
Here's an example to illustrate my current method:
I might have a view object that spawns a DeleteObjectCommand instance due to some user action, passing references to two of its own private member functions (one for success, one for failure: let's say "deleteObjectSuccessHandler()" and "deleteObjectFailureHandler()" in this example) as callback function references to the command class's constructor.
Then the command object would repeat this pattern with its connection to the "data access" object.
When the RPC over the network has successfully been completed (or has failed), the appropriate callback functions are called, first by the "data access" object and then the command object, so that finally the view object that instantiated the operation in the first place gets notified by having its deleteObjectSuccessHandler() or deleteObjectFailureHandler() called.
I'll try one more idea:
Have your Data Access Object return their own AsyncTokens (or some other objects that encapsulate a pending call), instead of the AsyncToken that comes from the RPC call. So, in the DAO it would look something like this (this is very sketchy code):
public function deleteThing( id : String ) : DeferredResponse {
var deferredResponse : DeferredResponse = new DeferredResponse();
var asyncToken : AsyncToken = theRemoteObject.deleteThing(id);
var result : Function = function( o : Object ) : void {
deferredResponse.notifyResultListeners(o);
}
var fault : Function = function( o : Object ) : void {
deferredResponse.notifyFaultListeners(o);
}
asyncToken.addResponder(new ClosureResponder(result, fault));
return localAsyncToken;
}
The DeferredResponse and ClosureResponder classes don't exist, of course. Instead of inventing your own you could use AsyncToken instead of DeferredResponse, but the public version of AsyncToken doesn't seem to have any way of triggering the responders, so you would probably have to subclass it anyway. ClosureResponder is just an implementation of IResponder that can call a function on success or failure.
Anyway, the way the code above does it's business is that it calls an RPC service, creates an object encapsulating the pending call, returns that object, and then when the RPC returns, one of the closures result or fault gets called, and since they still have references to the scope as it was when the RPC call was made, they can trigger the methods on the pending call/deferred response.
In the command it would look something like this:
public function execute( ) : void {
var deferredResponse : DeferredResponse = dao.deleteThing("3");
deferredResponse.addEventListener(ResultEvent.RESULT, onResult);
deferredResponse.addEventListener(FaultEvent.FAULT, onFault);
}
or, you could repeat the pattern, having the execute method return a deferred response of its own that would get triggered when the deferred response that the command gets from the DAO is triggered.
But. I don't think this is particularly pretty. You could probably do something nicer, less complex and less entangled by using one of the many application frameworks that exist to solve more or less exactly this kind of problem. My suggestion would be Mate.
Many of the Flex RPC classes, like RemoteObject, HTTPService, etc. return AsyncTokens when you call them. It sounds like this is what you're after. Basically the AsyncToken encapsulates the pending call, making it possible to register callbacks (in the form of IResponder instances) to a specific call.
In the case of HTTPService, when you call send() an AsyncToken is returned, and you can use this object to track the specific call, unlike the ResultEvent.RESULT, which gets triggered regardless of which call it is (and calls can easily come in in a different order than they were sent).
The AbstractCollection is the best way to deal with Persistent Objects in Flex / AIR. The GenericDAO provides the answer.
DAO is the Object which manages to perform CRUD Operation and other Common
Operations to be done over a ValueObject ( known as Pojo in Java ).
GenericDAO is a reusable DAO class which can be used generically.
Goal:
In JAVA IBM GenericDAO, to add a new DAO, the steps to be done is simply,
Add a valueobject (pojo).
Add a hbm.xml mapping file for the valueobject.
Add the 10-line Spring configuration file for the DAO.
Similarly, in AS3 Project Swiz DAO. We want to attain a similar feet of achievement.
Client Side GenericDAO model:
As we were working on a Client Side language, also we should be managing a persistent object Collection (for every valueObject) .
Usage:
Source:
http://github.com/nsdevaraj/SwizDAO