+2  A: 

Don't go directly to Omniture; go to a "middleman" which fetches the data.

I've never even heard of Omniture, but it sounds like senarios where your UI is going straight to the data layer - in which case you need a business logic layer in between. That's the principle, anyway.

  1. Create a layer of logic that handles all communication between the UI and Omniture.
  2. The first UI call hits the logic layer / controller, e.g: Logic.GetPromotion()
  3. When that happens have the logic call omniture - get it do one batch call that gets all the data, much as you've descibed.
  4. Pass the requested data (Logic.GetPromotion()) to whomever called it.
  5. When the other calls hot the logic layer, it pulls that data out of the information it's just received - not from omniture.

Basically it's the Lazy-Load pattern; with the various concerns seperated - I'm not sure if I'd call it MVC - just properly structured (?).

One potential gotcha with this approach is that your calls are async - the logic controller might get a second call while it's still waiting for the results to come back from the first. I haven't done anything along these lines myself, but there are plenty of multi-threading / concurrency type design patterns out there that will help.

Adrian K
This is not something that will solve my purpose.
Rachel
Try using an Http Proxy to see the requests going back and forth between the UI and Omniture; that might give you some insights as to what you need to do. If Omniture is responsible for making the UI components that make all the expensive calls then I don't think there's much you can do.
Adrian K
A: 

I assume all components make AJAX call at the page load time and gets loaded asynchronously.

Consider there are N number of components that are loaded. Hence there will be N number of AJAX calls made to the server.

With current implementation, on successful load of each component, call to Omniture is made.

Most browsers allow around maximum 2-5 active connections to the server. So above N calls will be executed at 2-5 concurrent calls at a time and will not gaurantee the order in with this calls complete.

We need to have a mechanisim to intercept AJAX calls to load a component, so then we can maintain list of this calls that are in progress and list of calls that are completed.

Once count of list of calls in progress is zero, all components have been loaded and we have info of each loaded component in list of completed AJAX calls.

Using list of info of each loaded component, make a single call to Omniture if it has required API. If Omniture, does not have API for bulk call, make a call to intermediate facade on server which will iteratively make a call to Omniture.

.

Have an API that will be used by components to make AJAX calls
Each time AJAX request is made for a component to load [new Ajax.Request(...)], 
    API adds component request info entry to requestInProgressList
Each time AJAX request is for a component is complete (function onComplete(...) callback), 
    API moves component request info entry from requestInProgressList to requestCompleteList
    IF requestInProgressList.count == 0 // No more pending requests
    THEN
        From requestCompleteList, collect the information for all the components into variable dataOmniture
        Clear requestCompleteList
        Make a call to Omniture to send dataOmniture information
    END
Gladwin Burboz
Does this compile?
JC
Can you explain your algorithm more clearly ?
Rachel
@JC: This is an algorithm, it won't compile. You need to implement it in JavaScript for it to run.
Gladwin Burboz
@Rachel: I updated solution with more info. Hope this is more verbose.
Gladwin Burboz