Couldn't there be a special URL for a CDN, like an "are you alive"
type url, that we load first, and then, if that works (and quickly),
we proceed to load the other files. If not, the CDN is assumed to be
"down" (or at least too slow), so we failover to loading local
versions.

This is a really rough sketch of an idea, and admittedly pretty ugly,
but I think it might work (or something close to it).

Here's a working example:  http://test.getify.com/cdn-failover/

That example fakes a CDN alive check by calling a URL called
"cdnalive" which will randomly choose to:
1. return a 404
2. delay 5 seconds to respond
3. respond right away with a simple script snippet that says "var
googlecdn = true;"

If the Google CDN implemented a check url such as that, you could call
it to test if the CDN was gonna respond quickly, and then decide to
where to load scripts from accordingly.

The logic is very simple (though it looks a little bit complicated).
Basically, just set a 2 (or whatever length) second timeout, then try
to load the "alive" check url. If it loads in time, and successfully
(defining the "googlecdn" variable), proceed to load the scripts from
the CDN. Otherwise, load the scripts from the local copies.


And here's the code for those who want to see it:

<script type="text/javascript">
function initScripts() {
   // jquery and jquery-ui are now loaded, go for it!
   alert("jQuery and jQueryUI loaded!");
}

var aliveFailed = null, cdnFailed = false;

(function(global){
   aliveFailed = setTimeout(function(){
      cdnFailed = true;
      addScript("jquery.min.js", // load scripts from local instead
         function(){
            addScript("jquery-ui.min.js",
               initScripts
            );
         }
      );
   },2000);  // only wait 2 seconds for CDN to respond, otherwise pull
from local copies

   var head = document.getElementsByTagName("head"), // this is a
"live" DOM collection, so will update whenever HEAD is ready
        script_done = {};

   global.addScript = function(src,onload) {
      var args = arguments;
      if (head[0] == null) { // head not ready yet
         setTimeout(function(){addScript.apply(null,args);},25);
      }
      var script = document.createElement("script");
      script.type = "text/javascript";
      script.onload = script.onreadystatechange = function(){
         if (!(script.readyState && script.readyState!=="complete" &&
script.readyState!=="loaded") && typeof script_done[script.src] ===
"undefined") { // successful load detected
            script_done[this.src] = true;
            script.onload = script.onreadystatechange = null;
            onload();
         }
      };
      script.src = src;
      head[0].appendChild(script);
   }
})(window);
</script>
<script rel="googlecdnalive" src="[**http://ajax.googleapis.com/alive?
**]" type="text/javascript"></script>
<script type="text/javascript">
   if (!cdnFailed && typeof googlecdn !== "undefined") { //
'googlecdn' defined in the cdn alive check
      clearTimeout(aliveFailed);
      addScript("http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/
jquery.min.js",  // CDN is up, pull scripts from there
         function(){
            addScript("http://ajax.googleapis.com/ajax/libs/jqueryui/
1.7.2/jquery-ui.min.js",
               initScripts
            );
         }
      );
   }
</script>



On Oct 10, 11:02 am, Steven Black <[email protected]> wrote:
> I just tested this in a variety of ways and both John's and Phil's
> methods work great and you're right: appendChild and prependChild both
> work.
>
> Cool!
>
> **--**  Steve
>
> On Oct 9, 10:44 pm, Michael Geary <[email protected]> wrote:
>
>
>
> > prependChild or appendChild wouldn't make any difference; they're both
> > asynchronous.
>
> > Regarding that sub-packet-sized package with a fast timeout, how would you
> > implement that short of recompiling the browser? :-)
>
> > -Mike
>
> > On Fri, Oct 9, 2009 at 6:54 PM, Steven Black <[email protected]> wrote:
>
> > > First of all, thanks @jresig because that's just way too elegant.  I
> > > was anticipating something far more complex.
>
> > > A couple of questions:
>
> > > Ifhttp://cdn/jQuery.jsfails, we want the local-domain jQuery.js to
> > > load next, BEFORE the any other subsequent script which is likely a $
> > > (function(){}) or a call for plugin, both of which have a jQuery
> > > predicate.  So I don't sense that Phil's ...('head')[0].appendChild
> > > (script) would work reliably.  Am I wrong about that?  Does this
> > > really work as you expect, Phil?  I would expect a prependChild(), no?
>
> > > Second, Dave raises another crux of the matter: we need to bail to the
> > > failover ASAP, ideally within a second or two.  It's almost as if we
> > > need the CDNs to also provide a sub-packet-sized package we could
> > > request, wrapped inside a very short timeout to bail to the failover.
>
> > > **--**  Steve
>
> > > On Oct 9, 9:10 am, Dave Methvin <[email protected]> wrote:
> > > > > I took this great idea and went ahead implementing it on a few sites I
> > > > > maintain using different syntax.
>
> > > > It's more than a syntax change; it's entirely different semantics.
> > > > Your version fetches a copy of jQuery asynchronously. If there is
> > > > a .ready() handler below that block of code, jQuery may not be loaded
> > > > by the time it is reached and you'll get errors. By using
> > > > document.write and a script tag, you can be guaranteed that the
> > > > browser won't proceed to run any code below it until it either loads
> > > > the script or gets an error back from the request (like a 404 or a
> > > > timeout).
>
> > > > I'd think the timeout situation is the most likely outcome when
> > > > Google's CDN is down, which means the user will see a blank screen for
> > > > 30 to 60 seconds before it even reaches the document.write anyway. So
> > > > it seems like you'd need to load the Google CDN version asynchronously
> > > > to prevent that. But that raises the question of what to show the user
> > > > while it's trying to find a reachable version of jQuery...- Hide quoted 
> > > > text -
>
> - Show quoted text -
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"jQuery Development" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/jquery-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to