Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Move refresh timeout into $.ajax.complete callback from success callback #261

Closed
wants to merge 3 commits into from

2 participants

Joe Flateau Steve Purcell
Joe Flateau

Otherwise, if Twitter responds with an error, we don't get any further refreshes

Joe Flateau joeflateau Set refresh timeout in a complete callback
Otherwise, if Twitter responds with an error, we don't get any further refreshes
9877a44
Steve Purcell
Collaborator

I have mixed feelings about this, because by far the most likely sources of errors are that a) the user has exceeded his rate limit, or b) the developer has messed something up -- continuing to make requests regardless isn't helpful in these cases.

What errors were you experiencing which you nonetheless wanted to retry?

-Steve

Joe Flateau

I'll try to track down the actual source, I have a feed refreshing every 4 seconds, so I would guess it's a rate limit problem.

Steve Purcell
Collaborator

Yeah, once you hit 150req/hr, you'll hit the rate limits. A 4 second refresh interval is a great way to ensure that! ;-)

Joe Flateau

Here's the HAR of the requrest, it has a 200 Status code but Chrome says the request failed and then the feed freezes.

{
  "startedDateTime": "2012-07-25T14:54:23.849Z",
  "time": 915,
  "request": {
    "method": "GET",
    "url": "http://search.twitter.com/search.json?&q=orangenation%20OR%20cusenation&rpp=4&page=1&include_entities=1&callback=jQuery1720986392725026235_1343227920004&_=1343228064206",
    "httpVersion": "HTTP/1.1",
    "headers": [
      {
        "name": "Accept-Encoding",
        "value": "gzip,deflate,sdch"
      },
      {
        "name": "Accept-Language",
        "value": "en-US,en;q=0.8"
      },
      {
        "name": "Cookie",
        "value": "guest_id=v1%3A133406703182484699; auth_token_session=true; secure_session=true; twll=l%3D1342546535; remember_checked=0; k=10.36.37.122.1343143302739095; pid=v3:1343167693703929752400687; __utma=43838368.865180207.1334599100.1343173436.1343226210.135; __utmb=43838368.2.10.1343226210; __utmc=43838368; __utmz=43838368.1343173436.134.73.utmcsr=newshowcase.sidearmsports.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __utmv=43838368.lang%3A%20en"
      },
      {
        "name": "Connection",
        "value": "keep-alive"
      },
      {
        "name": "Accept-Charset",
        "value": "ISO-8859-1,utf-8;q=0.7,*;q=0.3"
      },
      {
        "name": "Host",
        "value": "search.twitter.com"
      },
      {
        "name": "User-Agent",
        "value": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11"
      },
      {
        "name": "Accept",
        "value": "*/*"
      },
      {
        "name": "Referer",
        "value": "http://joef-showcase.sidearmsports.com/"
      }
    ],
    "queryString": [
      {
        "name": "",
        "value": ""
      },
      {
        "name": "q",
        "value": "orangenation%20OR%20cusenation"
      },
      {
        "name": "rpp",
        "value": "4"
      },
      {
        "name": "page",
        "value": "1"
      },
      {
        "name": "include_entities",
        "value": "1"
      },
      {
        "name": "callback",
        "value": "jQuery1720986392725026235_1343227920004"
      },
      {
        "name": "_",
        "value": "1343228064206"
      }
    ],
    "cookies": [
      {
        "name": "guest_id",
        "value": "v1%3A133406703182484699",
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "auth_token_session",
        "value": "true",
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "secure_session",
        "value": "true",
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "twll",
        "value": "l%3D1342546535",
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "remember_checked",
        "value": "0",
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "k",
        "value": "10.36.37.122.1343143302739095",
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "pid",
        "value": "v3:1343167693703929752400687",
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "__utma",
        "value": "43838368.865180207.1334599100.1343173436.1343226210.135",
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "__utmb",
        "value": "43838368.2.10.1343226210",
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "__utmc",
        "value": "43838368",
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "__utmz",
        "value": "43838368.1343173436.134.73.utmcsr=newshowcase.sidearmsports.com|utmccn=(referral)|utmcmd=referral|utmcct=/",
        "expires": null,
        "httpOnly": false,
        "secure": false
      },
      {
        "name": "__utmv",
        "value": "43838368.lang%3A%20en",
        "expires": null,
        "httpOnly": false,
        "secure": false
      }
    ],
    "headersSize": 967,
    "bodySize": 0
  },
  "response": {
    "status": 200,
    "statusText": "OK",
    "httpVersion": "HTTP/1.1",
    "headers": [
      {
        "name": "Date",
        "value": "Wed, 25 Jul 2012 14:54:24 GMT"
      },
      {
        "name": "Via",
        "value": "1.1 varnish, 1.1 varnish"
      },
      {
        "name": "Age",
        "value": "0"
      },
      {
        "name": "Transfer-Encoding",
        "value": "chunked"
      },
      {
        "name": "Status",
        "value": "200 OK"
      },
      {
        "name": "Connection",
        "value": "close"
      },
      {
        "name": "Content-Encoding",
        "value": "gzip"
      },
      {
        "name": "Server",
        "value": "tfe"
      },
      {
        "name": "X-Varnish",
        "value": "1831528195, 1831528194"
      },
      {
        "name": "Cache-Control",
        "value": "max-age=15, must-revalidate"
      },
      {
        "name": "Content-Type",
        "value": "application/javascript; charset=utf-8"
      },
      {
        "name": "Retry-After",
        "value": "0"
      }
    ],
    "cookies": [],
    "content": {
      "size": 40,
      "mimeType": "application/javascript",
      "compression": -22
    },
    "redirectURL": "",
    "headersSize": 359,
    "bodySize": 62
  },
  "cache": {},
  "timings": {
    "blocked": 0,
    "dns": 4,
    "connect": 82,
    "send": 0,
    "wait": 86,
    "receive": 743,
    "ssl": -1
  },
  "pageref": "page_11"
}
Steve Purcell
Collaborator

Odd. That request URL works fine for me. If there were rate-limiting issues, you'd have received a 40x rather than a 200. The bodySize of the response you received (62) looks hokey to me. Maybe transient network issues?

Joe Flateau

Yeah, that is my guess as well, I'll make one more change in a second, to get the Retry-After header and respect that

Joe Flateau Grab the Retry-After header
use that if it's there instead of the specified refresh_interval
498505d
Joe Flateau

That should take care of the Rate Limit problem

Joe Flateau Make the refresh more resilient
Sometimes jQuery.ajax.complete is never called causing refreshing to be
halted
96f7675
Joe Flateau joeflateau closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 25, 2012
  1. Joe Flateau

    Set refresh timeout in a complete callback

    joeflateau authored
    Otherwise, if Twitter responds with an error, we don't get any further refreshes
  2. Grab the Retry-After header

    Joe Flateau authored
    use that if it's there instead of the specified refresh_interval
Commits on Aug 1, 2012
  1. Make the refresh more resilient

    Joe Flateau authored
    Sometimes jQuery.ajax.complete is never called causing refreshing to be
    halted
This page is out of date. Refresh to see the latest.
Showing with 34 additions and 16 deletions.
  1. +34 −16 tweet/jquery.tweet.js
50 tweet/jquery.tweet.js
View
@@ -220,22 +220,40 @@
var outro = '<p class="tweet_outro">'+s.outro_text+'</p>';
var loading = $('<p class="loading">'+s.loading_text+'</p>');
if (s.loading_text) $(widget).not(":has(.tweet_list)").empty().append(loading);
- $.getJSON(build_api_url(), function(data){
- var list = $('<ul class="tweet_list">');
- var tweets = $.map(data.results || data, extract_template_data);
- tweets = $.grep(tweets, s.filter).sort(s.comparator).slice(0, s.count);
- list.append($.map(tweets, function(o) { return "<li>" + t(s.template, o) + "</li>"; }).join('')).
- children('li:first').addClass('tweet_first').end().
- children('li:odd').addClass('tweet_even').end().
- children('li:even').addClass('tweet_odd');
-
- $(widget).empty().append(list);
- if (s.intro_text) list.before(intro);
- if (s.outro_text) list.after(outro);
-
- $(widget).trigger("loaded").trigger((tweets.length === 0 ? "empty" : "full"));
- if (s.refresh_interval) {
- window.setTimeout(function() { $(widget).trigger("tweet:load"); }, 1000 * s.refresh_interval);
+ var forceRefreshTimeout;
+ var refresh = s.refresh_interval;
+
+ if (refresh) {
+ forceRefreshTimeout = setTimeout(function(){ $(widget).trigger("tweet:load"); }, 2000 * s.refresh_interval);
+ }
+
+ $.ajax({
+ url:build_api_url(),
+ dataType:'jsonp',
+ success: function(data){
+ var list = $('<ul class="tweet_list">');
+ var tweets = $.map(data.results || data, extract_template_data);
+ tweets = $.grep(tweets, s.filter).sort(s.comparator).slice(0, s.count);
+ list.append($.map(tweets, function(o) { return "<li>" + t(s.template, o) + "</li>"; }).join('')).
+ children('li:first').addClass('tweet_first').end().
+ children('li:odd').addClass('tweet_even').end().
+ children('li:even').addClass('tweet_odd');
+
+ $(widget).empty().append(list);
+ if (s.intro_text) list.before(intro);
+ if (s.outro_text) list.after(outro);
+
+ $(widget).trigger("loaded").trigger((tweets.length === 0 ? "empty" : "full"));
+ },
+ complete:function(jqXHR){
+ window.clearTimeout(forceRefreshTimeout);
+ if (jqXHR.getResponseHeader("Retry-After")) {
+ refresh = parseInt(jqXHR.getResponseHeader("Retry-After")) || refresh;
+ }
+
+ if (refresh) {
+ window.setTimeout(function() { $(widget).trigger("tweet:load"); }, 1000 * refresh);
+ }
}
});
}
Something went wrong with that request. Please try again.