Quantcast
Channel: West Wind Message Board Messages
Viewing all articles
Browse latest Browse all 10393

Re: Async

$
0
0
Re: Async
FoxInCloud
Re: Async
04/24/2012
03:33:54 AM
3HJ07N5Y5 Show this entire thread in new window
Gratar Image based on email address
From:
Thierry Nivelet (FoxInCloud)
To:
Attachments:
None
We might do that by a naming convention:

Object.extend(FoxInCloud, { AsyncCallBackClass1: function(lcID, status){ }, AsyncCallBackClass2: function(lcID, status){ }, etc. };

JavaScript being case-sensitive, looks pretty dangerous to maintain ...

You would want every entry to have its own asyncCallback code, no? You could not have one for an entire app. I think that is what Rick was getting at.


Might be easier with FoxInCloud as we have a standard javascript (FoxInCloud.js) cooperating with FAS ;)
What I would suggest is (names are temptative):

1- aw.vcx!awFrm.AsyncStart(class AS awAsyncWebRequest (AS wwAsyncWebRequest), classlib, parm1, parm2, etc.) AS awAsyncWebRequest.
awAsyncWebRequest.Init() writes this into standard awAJAX XML response:

<AsyncStart><class>class</class><id>lcID</id></AsyncStart>

2- When detecting this XML entry, FoxInCloud.js does this:

FoxInCloud.aAsync.push([lcID, window.setInterval(FoxInCloud.Async, 1000, class, lcID)]) // with proper context binding // an Array allows several async processes in parallel

3- FoxInCloud.Async(class, lcID) does the following:

this.ServerRequest('AsyncStatus' , null // no related DOM element , lcID // Server-side Async process ID , false // AJAX request is asynchronous )

4- awProcess.AsyncStatus() queries status based on lcID and adds this message to standard FiC XML response:

<AsyncStatus><class>class</class><id>lcID</id><status>user-defined status: 45%, [step1, step 2, ...], etc.</status></AsyncStatus>

When receiving this response, FoxInCloud executes a callback method:

this.AsyncCallBack(class, lcID, status); // status is whatever string was received from server above

5- Developer overrides FoxInCloud.AsyncCallBack() in xxx.js (javascript dedicated to FIC application):

Object.extend(FoxInCloud, { /* ... existing stuff ... *// AsyncCallBack: function(class, lcID, status){ switch (class) { case 'class1': switch (lcID) ... case 'class2': ... } }, /* ... other existing stuff ... *// });

Any thoughts or suggestions ?

Let me know what you come up with for this.

I've thought about this a bit in the past and never really figured out a good way to do to make this generic, because ultimately you have to store and forward the request and result data.

+++ Rick ---



We need to implement some standard mechanism to:
- start a wwAsyncWebRequest process on the server (e.g. aw.vcx!awFrm.async())
- send back process ID to client browser (lcID)
- have client browser (javascript) poll for completion based on that ID
- Provide a JS call back method for developer to implement some sort of status monitoring, e.g. a thermometer

Excellent reply, thanks. I had thought "this sounds like the server should be a separate component", but then I thought no, I am just imagining that.

The separate exe idea is great, it gives me the flexibility and separation of client data I need,.

Thanks again.


Tuvia,

The wwAsyncWebRequest component can go anywhere. Sufficiently vague for you? :-) But that's literally true as it's just the 'messaging' component that allows you to store and retrieve data for messaging.

As such it reqiures a client - which submits, requests status and receives a result/failure, and a server that retrieves a request from the 'queue', processes it, updates status and then stores a response.

The 'Server' can be implemented in any way you choose, but it almost always is separate from the Web Connection application - a standalone EXE or another service on another machine that polls the same database for requests. It makes no sense to have an async process in the same process as the Web Connection app since VFP's single threaded nature ties up the CPU when it's processing.

One typical workflow that I've used for this looks like this:

* Web Connection server is the client
* Receives a request from application to start processing
* Creates a new Message for processing
* At the same time starts a separate EXE that knows how to handle one or messages
(this will become your Async 'server' that runs one request)
* The 'server' picks up message and now starts processing the async task
* Server then sends updates into the message object and saves
* Client polls occasionally to see update status or at very least polls for completion
* Server finishes processing and updates message object to say it's completed
* Server exe shuts down
* Client polls and finds server is done
* Client retrieves result data stored in message
* Client displays result

How the server is implemented is up to you really. I like the idea of an EXE started so that EXE is active for the duration of one aysnc request processing. If multiple asyncs are requested new Exes start up. Another alternative is that you can just run a permanent server that is always running and polls for new incoming messages and then processes them one at a time. You can run one or more of these daemons depending on your load.

It works rather well and is pretty flexible actually. I've used this same approach in .NET as well and works there as well. Because the data is stored in plain Fox or SQL data you can also read it from other applications and interact with other technologies.

This component lives in the same space as MSMQ but IMHO is much easier to work with and more flexible.

Hope this helps,

+++ Rick ---








Viewing all articles
Browse latest Browse all 10393