Queueing Asynchronous Requests

Queueing Asynchronous Requests

Old forum URL: forums.lhotka.net/forums/t/9153.aspx


edreyes77 posted on Wednesday, June 30, 2010

Mr Rockford:
 
I have a question about loading different data aynchronously into several different ViewModels/Models on initialization.

I have a Silverlight client using just a WCF Service getting data from various sources. My Silverlight client is using the BxF framework and using CSLA Business Objects.  When I switched to BxF I found an initialization issue. 
 
I use to load all my data from a csla dataportal and when I received a reply I would then ask for more initialization data and continue until I received all the data I wanted.  It was literally requesting more data in Callbacks from the last request.  I did not like it at all, but it got the job done and let me focus on other things. 
 
now that I am using BXF, in the MainPagePresenter, I use the region to set some content window properties:
 
presenter.OnShowView += (view, region) => {
     if (0 == region.CompareTo ("EntityPanel")) {
      EntityPanel = view.ViewInstance;
     }
     else if (0 == region.CompareTo ("ReportTypePanel")) {
      ReportTypePanel = view.ViewInstance;
     }
    };
 
This works well, I have a lot more content to show and was wondering if this is the right way to do this?  It can get messy I think. 
 
But the real issue is that, I want to do this to get all my initialization data:
 
    Bxf.Shell.Instance.ShowView (
       typeof (NavigatorEntities).AssemblyQualifiedName,
       "entityViewModelViewSource",
       new EntityListViewModel (),
       "EntityPanel");
    Bxf.Shell.Instance.ShowView (
          typeof (NavigatorReportTypes).AssemblyQualifiedName,
          "reportTypeViewModelViewSource",
          new ReportTypeListViewModel (),
          "ReportTypePanel");
But If I don't comment the second message and allow it to run then the second callback will come back as a timeout error.  I use to get around that my daisy chaining requests for more data in my callbacks.  But I placed the callbacks in my respective ViewModels and I can't really daisy chain more requests for more required data.  Can you suggest what I might do?  I thought about using MSMQ, but that seems like an extreme thing to do.  I am sure I will run into situations like this over and over again. my WCF Service ordinarily would send this message to another Application Server, but I need to be able to handle one SL Client with only one Broker and one Application Server.  I can't predict in the future how many requests I will have cueued up from a WCF Service, and i don't want to have a whole bunch of Application Servers running just to suffice multiple queues from one client.

I think if I was writing the Application Server at this time as well then I would probably sandwich a request/reply to get all initialization data at one time, but it's legacy code that I am starting a migration path for it to be rewritten and broken apart and distributed and still have everything running.  And either way, I still need to handle getting lots of data in a chaining mechanism.  Would workflow work here?

Ed


RockfordLhotka replied on Wednesday, June 30, 2010

These sound like menu items you are loading? A list of entities and a list of reports?

You aren't accidentally using the SynchronizedWcfProxy data portal channel or something?

The data portal should allow multiple concurrent server requests to run independently. There are limits (set by Windows) on how many outstanding requests can run at a time, but certainly 2 requests can run concurrently.

Your "new EntityListViewModel()" line of code, for example, almost certainly returns instantly right? It just does a BeginRefresh() to start the async load, and that's it?

So what should happen with the code you show, is that the entity view and viewmodel should initialize and be displayed, then the report view/viewmodel - and at some point after they've been displayed, their data will arrive and appear on the screen.

I don't think workflow will help - at least WF - since that's a server-side construct. Or is your problem that the two server requests are blocking each other on the server for some reason?

edreyes77 replied on Friday, July 09, 2010

you are right.  The dataportal allows multiple server requests and so does my wcf service.  But the application servers do not allow multiple concurrent requests.   This is an issue that needs to be fixed by either queueing messages at the client, or in the middle wcf service.  I am not allowed to change the application server.  I think queueing at the client would be the cleanest.  I have a Bridge that is a simple singleton object to all my methods in my business objects that will create asynchronous calls to a wcf service.  I think this would be a good place to insert some type of orchestration, what I thought would be a WF function.  Maybe not. 

Ed

RockfordLhotka replied on Saturday, July 10, 2010

Queuing at the client seems somewhat pointless, at least if you have more than one user? Wouldn't multiple users conflict as well?

It seems like your only option is to implement a queuing scheme on your app server (on the server-side of the data portal), so you block client requests until they can be handled by your single-process server. You could run into timeout issues doing this though, so some serious testing is indicated...

RockfordLhotka replied on Saturday, July 10, 2010

One last thing though. If by some strange miracle multiple users can't conflict, but requests from one user do (which I can't understand), you might look at the SynchronizedWcfProxy. Its purpose is for testing, but it does client-side blocking to ensure that only one data portal request is sent to the server at a time. I never envisioned it being used for production purposes, since it obviously has a terrible impact on throughput in a real app - but it might be pretty close to what you need.

Copyright (c) Marimer LLC