mikehostetler / amplify

AmplifyJS
http://amplifyjs.com
GNU General Public License v2.0
1.45k stars 143 forks source link

Non-duplication of concurrent requests #51

Closed brianmhunt closed 12 years ago

brianmhunt commented 12 years ago

When multiple concurrent requests occur, it would be valuable for amplify.js to reduce these requests to one ajax call.

For example, given:

amplify.request.define("X", "ajax", {
         url: "/x/{id}",
         dataType: "json",
         cache: true,
         type: "GET"
     });

amplify.request("X", { id: 1}, function () {});
amplify.request("X", { id: 1}, function () {});

Right now when I run this code (e.g. http://jsfiddle.net/Xg9gn/) two AJAX requests occur.

Obviously caching cannot occur until a request completes.

However, I believe a preferable model would be for the first request to block all future identical requests; those future requests would however subscribe to the results of the first request.

An option to force an AJAX request may be prudent (though I cannot think of a use case offhand).

Just a thought! :)

scottgonzalez commented 12 years ago

Requests should not block. What you probably want is throttling that will put concurrent requests on hold and then respond with the cached response when the first request completes.

brianmhunt commented 12 years ago

Sorry; "block" was a misleading word. The idea is that the request is not being 'blocked' in the async sense, but rather the request is added to a queue rather than submitting multiple duplicate AJAX requests. Here's some rough code:

function request(resource_name, callback) {
   this_request = some_lookup_of_requests.get(resource_name);

   if this_request.is_outstanding(resource_name) {
      // by outstanding - the request has been made, and a response not
      // yet received

     subscribe(this_request, callback); 
     // when the ajax returns, the results are published
   } else {
      amplify.request(resource_name, function (...) { 
        this_request.no_longer_outstanding();
        // make sure that subsequent requests do not subscribe when
        // no ajax request is outstanding

        callback(...); // tell the caller

        publish(this_request, ...); // notify any subscribers
      });
   }
}

This is not really caching in the traditional sense; it may be better to describe it as a subscriber/publisher alternative to multiple concurrent requests.

I am not sure if this is something amplify.js would want - but since it reduces the need for developers to think about the need for multiple concurrent requests I tend to think it is helpful - but in any case I hope the above clarifies what I had intended.

Plus it's fun. :)

Cheers.

mariusfilipowski commented 11 years ago

I am facing the same problem. It would be very cool to have such a mechanisms. Or how it be implemented on our own? Any hints?