20 December 2009 ~ Comments

TweetSharp Preview 21 – Retry and Timeout

The holidays bring good things, and for our users that means new features! Preview 21 has been released and contains two significant new features you can use to make your apps more robust.

First, we have implemented configurable automatic retries. If your Twitter API call fails for reasons out of your control (such as the infamous FailWhale), you can have TweetSharp automatically retry the request for you a specific number of times. If it exhausts the retries before succeeding, you will get back the same type of response object as you have in the past when the query failed on the first try.

The failures TweetSharp can detect and retry on are as enumerated in the “RetryOn” enum:

[Flags]
public enum RetryOn
{
    Never = 0,
    FailWhale = 1,
    TwitterError = 2,
    Timeout = 4,
    Network = 12, //includes Timeout
    FailWhaleOrNetwork = FailWhale | Network
}

For the most part, you’ll probably want to use “FailWhaleOrNetwork” for your queries. “TwitterError” is any HTTP response code other than 200 OK, or 502 (FailWhale) and generally means something is wrong with your query, so retrying on that probably won’t yield a different result – but hey, it’s your app, not ours, so it’s in there if you need it for something.

“Network” includes stuff like DNS and connection failures, basically anything that is neither a FailWhale nor an non-success HTTP response. It also includes timeouts (see below).

Timeouts are..well, timeouts. The request was sent off to the Twitter servers, but there has been no response for some time and TweetSharp gave up. The default timeout is determined by the system, but is somewhere in the neighbourhood of 2 minutes on most systems, so you probably won’t want to set your retry limit to more than a couple of times if you don’t set a shorter timeout (more on that later).

Here’s some sample code that sets up a query with desired retry behavior:

const int FIVE_TIMES = 5; 

var twitter = FluentTwitter.CreateRequest()
    .Configuration.UseAutomaticRetries(RetryOn.FailWhaleOrNetwork, FIVE_TIMES)
    .Statuses().OnPublicTimeline().AsJson();

var result = twitter.Request();
//the TwitterResult object contains the count of retries required
Console.WriteLine("Query was retried {0} times", result.Retries);
if (result.Retries > 0)
{
    //requests that were retried contain the TwitterResult
    //object for the previous, failed attempt
    var previousResult = result.PreviousResult;
    while(previousResult != null)
    {
        //note we also now provide the full WebException object for failed requests
        Console.WriteLine("Previous Attempt Result:{0}", previousResult.Exception);
        previousResult = result.PreviousResult;
    }
}

Retries work on all types of queries.

Secondly, we’ve made the timeout value configurable, so if the system default is too long for you, you can tell TweetSharp to use a shorter timeout value and it will happily oblige.

Usage is pretty simple:

var twitter = FluentTwitter.CreateRequest()
    .Configuration.TimeoutAfter(5.Seconds())
    .Statuses().OnPublicTimeline().AsJson();

That’s it. This obviously works well in conjunction with retries, but doesn’t require that you set up for automatic retries, you can add this on a non-retrying query as well.

Lastly, if you want to test out these features (or your app’s error handling in general), we set up a resource to test these features that you can use as well. If you make your normal twitter requests though the Transparent Proxy at http://failwhale.diller.ca you will ALWAYS get back a FailWhale response. And while it’s not as clean as using a transparent proxy, http://failwhale.diller.ca/timeout.php?delay=x can be used to simulate a timeout. Just pass the number of seconds you want it to stall before responding as the ‘delay’ parameter in place of x (works with both GET and POST). To do this via TweetSharp you need to use the .Direct method:

 var twitter = FluentTwitter.CreateRequest()
            .AuthenticateAs(TWITTER_USERNAME, TWITTER_PASSWORD)
            .Configuration.UseTransparentProxy("http://failwhale.diller.ca/")
            .Configuration.TimeoutAfter(5.Seconds())
            .Direct("/timeout.php?delay=6")
            .Post();

The failwhale server is unofficial, unsupported, may be down at any time, and may go down some day and never come back. It’s easy to set up your own, so if you prefer a locally-controlled version of your own with guaranteed availability and need a hand configuring it, just ask a question on the forum and we’ll be happy to help.

Happy holidays to all our users. We have even more features planned for 2010, and I’m sure Twitter does too, so it should be another busy year for us all. Best Wishes.

  • proxdeveloper
    Hey folks, first of all great library, I implementing this library in my twitter desktop client, 2 days ago everything was working nice and fluent, today I can not get the request token

    //-----------------
    _consumerKey = Manager.TwitterSession.ClientInfo.ConsumerKey;
    _consumerSecret = Manager.TwitterSession.ClientInfo.ConsumerSecret;
    //get a request token
    var getRequestTokenRequest = FluentTwitter.CreateRequest()
    .Authentication.GetRequestToken(_consumerKey, _consumerSecret);
    var response = getRequestTokenRequest.Request();
    _requestToken = response.AsToken();
    //-----------------

    Could anyone help me out please, this is not the first time I'm facing this problem.

    **I've registered 3 different applications and different twitter accounts (different consumer secret and keys) to check if there was a problem with my registered application but still without results.
    I've tried the registered applications with the sample OAuth project available for download in the downloads section and the app is having the same problem.

    So I'm pretty sure it's not my code that's wrong.
  • guest
    has anyone figured out the api.twitter.com problem. The "join the conversation" link points to api.twitter.com/signup. This page does not exist. However, twitter.com/signup works. Seems like no one at twitter or anywhere wants to acknowledge this issue. This is very frustrating.

    Thanks to anyone that has an answer
  • We don't know why that is, but it is on Twitter's side and not something we can change. You can work around this for now by simply using the GetAuthorizationUrl() method, and then doing a string replace on "http://api.twitter.com" to "http://twitter.com" and it will work fine.
  • Awesome. You guys rock!
blog comments powered by Disqus