Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'override-jQuery.ajax'

  • Loading branch information...
commit 62ba7ba7f1bf74db276cddb7b51e99091ad9f310 2 parents 3586ae4 + da97b3a
execjosh execjosh authored
63 src/jquery.ajaxretry.js
View
@@ -23,28 +23,46 @@
DEF_DELAY_FUNC = function(i){
return Math.floor(Math.random() * ((2 << i) - 1));
},
+ DEF_ERROR_CODES = [502,503,504],
DEF_SLOT_TIME = 1000,
DEF_OPTS = {
attempts: DEF_ATTEMPTS,
cutoff: DEF_CUTOFF,
delay_func: DEF_DELAY_FUNC,
+ error_codes: DEF_ERROR_CODES,
slot_time: DEF_SLOT_TIME,
tick: NOP_FUNC
},
- ajaxWithRetry = function(req){
+ original_ajax_func = $.ajax,
+ ajaxWithRetry = function(settings){
+ settings = $.extend(true, {}, $.ajaxSettings, settings);
+
+ if (!settings.retry) {
+ return original_ajax_func(settings);
+ }
+
var failures = 0,
- opts = $.extend(true, {}, DEF_OPTS, req.retry || {}),
- orig_err_func = req.error || NOP_FUNC;
+ opts = $.extend(true, {}, $.ajaxRetrySettings, settings.retry),
+ orig_err_func = settings.error || NOP_FUNC;
- function retry_delay(time) {
- if (0 > time) {
- $.ajax(req);
+ function retry_delay(ticks) {
+ if (0 > ticks) {
+ original_ajax_func(settings);
}
else {
// Send tick event to listener
- window.setTimeout(function(){opts.tick(time)}, 0);
+ window.setTimeout(function(){
+ opts.tick({
+ attempts: opts.attempts,
+ cutoff: opts.cutoff,
+ failures: failures,
+ slot_time: opts.slot_time,
+ ticks: ticks
+ })
+ }, 0);
+
// Wait for slot_time
- window.setTimeout(function(){retry_delay(time - 1)}, opts.slot_time);
+ window.setTimeout(function(){retry_delay(ticks - 1)}, opts.slot_time);
}
}
@@ -56,9 +74,10 @@
opts.delay_func = opts.delay_func || DEF_DELAY_FUNC;
// Override error function
- req.error = function(xhr_obj, textStatus, errorThrown){
+ settings.error = function(xhr_obj, textStatus, errorThrown){
+ var can_retry = 0 <= $.inArray(xhr_obj.status, opts.error_codes);
failures++;
- if (failures >= opts.attempts) {
+ if (!can_retry || failures >= opts.attempts) {
// Give up and call the original error function
window.setTimeout(function(){orig_err_func(xhr_obj, textStatus, errorThrown)}, 0);
}
@@ -68,14 +87,24 @@
}
};
- return $.ajax(req);
- };
+ // Save the XHR object for reuse!
+ var xhr = original_ajax_func(settings);
+ settings.xhr = function(){
+ return xhr;
+ };
- ajaxWithRetry.retrySetup = function(opts){
- DEF_OPTS = $.extend(true, DEF_OPTS, opts || {});
- return DEF_OPTS;
- };
+ return xhr;
+ },
+ ajaxRetrySetup = function(opts){
+ DEF_OPTS = $.extend(true, DEF_OPTS, opts);
+ $.ajaxRetrySettings = DEF_OPTS;
+ return DEF_OPTS;
+ };
- $['ajaxWithRetry'] = ajaxWithRetry;
+ $['ajaxRetrySettings'] = DEF_OPTS;
+ $['ajaxRetrySetup'] = ajaxRetrySetup,
+ $['ajax'] = ajaxWithRetry;
})(jQuery);
+// vim: ts=4:sw=4:sts=4:noet:
+
4 test/test.css
View
@@ -0,0 +1,4 @@
+table {border:none;}
+th {text-align:right;}
+td {text-align:center;}
+#ajax, #ajax-vals, #ajaxRetrySetup {width:100%;}
81 test/test.html
View
@@ -3,10 +3,7 @@
<head>
<meta charset="utf-8" />
<title>TEST - jQuery Ajax Retry</title>
- <style type="text/css">
- table {border:none;}
- th {text-align:right;}
- </style>
+ <link href="test.css" type="text/css" rel="stylesheet" />
</head>
<body>
<table border="0" cellpadding="0" cellspacing="0">
@@ -23,7 +20,23 @@
<td><input type="text" id="slot_time" value="" /></td>
</tr>
<tr>
- <td colspan="2"><input type="button" id="run" value="Run" /></td>
+ <th><label for="http_code">Http Code:</label></th>
+ <td><select id="http_code"></select></td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <center>
+ <table border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td><input type="button" id="ajax" value="$.ajax()" /></td>
+ <td><input type="button" id="ajax-vals" value="$.ajax({})" /></td>
+ </tr>
+ <tr>
+ <td colspan="2"><input type="button" id="ajaxRetrySetup" value="$.ajaxRetrySetup()" /></td>
+ </tr>
+ </table>
+ </center>
+ </td>
</tr>
</table>
@@ -31,62 +44,8 @@
<script src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
<script src="../src/jquery.ajaxretry.js"></script>
- <script>
- (function($) {
- // Backoff tick callback
- function on_tick(count) {
- var minutes = Math.floor(count / 60),
- seconds = count % 60,
- display = seconds + '';
-
- if (0 < minutes) {
- display = [minutes, '', display].join('');
- }
-
- $('#page').html('<div>' + display + '後にリトライします</div>');
- }
-
- // Error handler
- function on_error() {
- $('#page').html("<div>OnError</div>");
- }
-
- // Success handler
- function on_success(data) {
- $('#page').html("<div>OnSuccess<br />" + data + "</div>");
- }
-
- // Set-up
- $(document).ready(function(){
- var retry_defaults = $.ajaxWithRetry.retrySetup({
- attempts: 30,
- cutoff: 7,
- slot_time: 100,
- });
-
- $('#attempts').val(retry_defaults.attempts);
- $('#cutoff').val(retry_defaults.cutoff);
- $('#slot_time').val(retry_defaults.slot_time);
-
- $('#run').click(function(){
- var retry_opts = {
- attempts: $('#attempts').val(), // Attempts after which to give up
- cutoff: $('#cutoff').val(), // Attempts after which to stop exponentiation
- tick: on_tick, // Tick callback
- slot_time: $('#slot_time').val() // Slot time (duration between ticks)
- };
- $.ajaxWithRetry({
- url: 'this/file/does/not/exist',
- retry: retry_opts,
- error: on_error,
- success: on_success,
- async: true,
- cache: false
- });
- });
- });
- })(jQuery);
- </script>
+ <script src="test.js"></script>
+<!-- vim: set ts=4 sw=4 sts=4 noet :-->
</body>
</html>
198 test/test.js
View
@@ -0,0 +1,198 @@
+// vim: ts=4:sw=4:sts=4:noet:
+(function($) {
+ // Backoff tick callback
+ function on_tick(backoff_info) {
+ var count = backoff_info.ticks,
+ minutes = Math.floor(count / 60),
+ seconds = count % 60,
+ display = seconds + '';
+
+ if (0 < minutes) {
+ display = [minutes, '', display].join('');
+ }
+
+ $('#page').html([
+ '<div>',
+ backoff_info.attempts, '回中',
+ backoff_info.failures, '回失敗していますが、',
+ display, '後にリトライします',
+ '(slot_time:', backoff_info.slot_time, '',
+ '</div>'
+ ].join(''));
+ }
+
+ // Error handler
+ function on_error(xhr, status, error) {
+ $('#page').html(['<div>OnError<br />', xhr.status, ', ', status, ', ', error, '</div>'].join(''));
+ enableGui(true);
+ }
+
+ // Success handler
+ function on_success(data, status, xhr) {
+ $('#page').html(['<div>OnSuccess<br />', xhr.status, ', ', status, ' -- ', data, '</div>'].join(''));
+ enableGui(true);
+ }
+
+ // Complete handler
+ function on_complete(xhr, status) {
+ console.log(['OnComplete -- ', xhr.status, ', "', status, '"'].join(''));
+ }
+
+ var elmIds = [
+ '#ajax',
+ '#ajax-vals',
+ '#ajaxRetrySetup',
+ '#attempts',
+ '#cutoff',
+ '#slot_time',
+ '#http_code'
+ ].join(', ');
+
+ function enableGui(enable){
+ if (!enable) {
+ $(elmIds).attr('disabled','disabled');
+ }
+ else {
+ $(elmIds).removeAttr('disabled');
+ }
+ }
+
+ // Set-up
+ $(document).ready(function(){
+ var ajaxSettings = {
+ url: 'test.php',
+ error: on_error,
+ success: on_success,
+ complete: on_complete,
+ async: true,
+ cache: false
+ };
+
+ function setup_ui() {
+ var def_opts = {
+ attempts: 8,
+ cutoff: 5,
+ slot_time: 100,
+ },
+ // http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
+ http_codes = {
+ '1xx Informational':[
+ '100 Continue',
+ '101 Switching Protocols',
+ '102 Processing'
+ ],
+ '2xx Success':[
+ '200 OK',
+ '201 Created',
+ '202 Accepted',
+ '203 Non-Authoritative Information',
+ '204 No Content',
+ '205 Reset Content',
+ '206 Partial Content',
+ '207 Multi-Status'
+ ],
+ '3xx Redirection':[
+ '300 Multiple Choices',
+ '301 Moved Permanently',
+ '302 Found',
+ '303 See Other',
+ '304 Not Modified',
+ '305 Use Proxy',
+ '306 Switch Proxy',
+ '307 Temporary Redirect'
+ ],
+ '4xx Client Error':[
+ '400 Bad Request',
+ '401 Unauthorized',
+ '402 Payment Required',
+ '403 Forbidden',
+ '404 Not Found',
+ '405 Method Not Allowed',
+ '406 Not Acceptable',
+ '407 Proxy Authentication Required',
+ '408 Request Timeout',
+ '409 Conflict',
+ '410 Gone',
+ '411 Length Required',
+ '412 Precondition Failed',
+ '413 Request Entity Too Large',
+ '414 Request-URI Too Long',
+ '415 Unsupported Media Type',
+ '416 Requested Range Not Satisfiable',
+ '417 Expectation Failed',
+ '418 I\'m a teapot',
+ '422 Unprocessable Entity',
+ '423 Locked',
+ '424 Failed Dependency',
+ '425 Unordered Collection',
+ '426 Upgrade Required',
+ '449 Retry With',
+ '450 Blocked by Windows Parental Controls'
+ ],
+ '5xx Server Error':[
+ '500 Internal Server Error',
+ '501 Not Implemented',
+ '502 Bad Gateway',
+ '503 Service Unavailable',
+ '504 Gateway Timeout',
+ '505 HTTP Version Not Supported',
+ '506 Variant Also Negotiates',
+ '507 Insufficient Storage',
+ '509 Bandwidth Limit Exceeded',
+ '510 Not Extended'
+ ]
+ },
+ opt_list = [];
+
+ $('#attempts').val(def_opts.attempts);
+ $('#cutoff').val(def_opts.cutoff);
+ $('#slot_time').val(def_opts.slot_time);
+
+ $.each(http_codes, function(key, val){
+ var grp = [];
+ $.each(val, function(){
+ grp.push(['<option>', this, '</option>'].join(''));
+ });
+ opt_list.push([
+ '<optgroup label="', key, '">',
+ grp.join(''),
+ '</optgroup>'
+ ].join(''));
+ });
+
+ $('#http_code').html(opt_list.join(''));
+ }
+
+ function getRetryOpts() {
+ return {
+ attempts: $('#attempts').val(), // Attempts after which to give up
+ cutoff: $('#cutoff').val(), // Attempts after which to stop exponentiation
+ slot_time: $('#slot_time').val() // Slot time (duration between ticks)
+ };
+ }
+
+ function initiateAjax(opts) {
+ var opts = {
+ retry: opts,
+ data: {http_code:$('#http_code').val()}
+ };
+ $.ajax($.extend(true, {}, ajaxSettings, opts));
+ }
+
+ setup_ui();
+
+ $('#ajax').click(function(){
+ enableGui(false);
+ initiateAjax($.extend(true, {}, $.ajaxRetrySettings, {tick: on_tick}));
+ });
+
+ $('#ajax-vals').click(function(){
+ enableGui(false);
+ initiateAjax($.extend(true, getRetryOpts(), {tick: on_tick}));
+ });
+
+ $('#ajaxRetrySetup').click(function(){
+ $.ajaxRetrySetup(getRetryOpts());
+ });
+ });
+})(jQuery);
5 test/test.php
View
@@ -0,0 +1,5 @@
+<?php
+$http_code = (isset($_GET['http_code'])) ? $_GET['http_code'] : '404 Not Found';
+header("HTTP/1.1 {$http_code}");
+print_r($_GET);
+?>
Please sign in to comment.
Something went wrong with that request. Please try again.