Playing with AppHarbor, Twitter and WebAPI.

What?

This sample application is very contrived, and came out of a throw away twitter account creation joke.

what started it

Landing Page: usedguids.apphb.com

Usage Info: gist.github.com/3964492

Service Features

  1. Submit a Guid, have it reserved
  2. Will inform you if it’s taken, or ok.
  3. Tweets

Tech Details / Steps

  • File, New, Web Api Project
  • ASP.NET 4.5 Web Api Controller
  • PM> Install-Package TweetSharp (nuget link, github link)
  • Git push to remote repo on BitBucket
  • AppHarbor link to BitBucket account (this was great, very easy)
  • Select an app name usedguids.apphb.com

Api Controller Logic

    public class UsedGuidController : ApiController
    {
        public HttpResponseMessage Post(UsedGuidInputModel ug)
        {
            //check for duplicates,
            //twitter authenticate, tweet
            //save guid
            //return new HttpResponseMessage(what_happened)
        }
    }

Conclusion

It’s up and running, we’ll see how stable it is. In this case the code is very sloppy, the focus was to get this concept up and running, so I decided to host it on BitBucket where I have private repositories on a free account.

The AppHarbor experience was great, no fuss to get it up and running, via the authorise AppHarbor app action when I was taken to BitBucket. Even setting up a back end store was very easy.

app harbor ui

The hardest part was working out how to deal with the Twitter API, and that was only tricky because I was in a hurry to just get it working, without reading enough documentation.

It’s unlikely I’ll make time to tidy up that code so it can be of any reasonable use to anyone, there’s too many hack points to get it operational, in particular around twitter API keys, for the application that performs the posting, and the user linked to the account. Not to mention hard coded connection strings with passwords in them. Quite a long list of what-not-to-do.

I did like that the wizard does warn you of such bad behaviour. There’s some insight into the storage model on the back end 😉

EfDataModelCreation

Advertisements

Queuing ajax calls to ASP.NET WebApi Controllers

Objective

To halt processing of subsequent ajax calls after one causes an error.

Why

Any actions related to a similar set of data (or concept) will all go through the same queue. This way if something falls over during processing of any given request, halting the processing of further requests should help not worsen things, or at least avoid subsequent errors that are a direct result of the first error.

When something unexpected has happened it’s likely the underlying system data is not in a valid state. Further actions may complicate things, possibly making matters worse. But more likely further actions will also error and we shouldn’t subject the system to having to handle them. So the solution is to get the user to reload the application into a known good state, i.e. complete fresh request of data.

There’s a competing concern that particular user actions may be desirable to have processed even after particular unknown/unexpected errors occur, but for now we’re going to assume these are rarer and can be dealt with specifically simply by having them bypass this queue (or make use of an alternate queue).

How

A toggled case
– After an error set a flag that will keep prompting the user to reload the page after an error.

A fixed case
– Do not process items already queued up in the processing queue.

Queue entry management

This part is simple. Most of the code is plumbing around building up the ajaxQueue call.

#CoffeeScript
class ActionCommandQueue

    validState: true
    
    #todo: surface the console log issues to the user

    sendData: (url, data, type, settings) =>
        settings = settings || {}
        settings.url = url
        settings.data = JSON.stringify(data)
        settings.type = type
        settings.contentType = 'application/json; charset=utf-8'
        settings.error = @onError
        if @validState
            $.ajaxQueue(settings)
        else
            console.log "You need to reload the page to continue. (click here)."

    onError: (xhr, status, error) =>
        @validState = false
        console.log "Sorry that action failed. Please reload the page and try again"

Usage

    #CoffeeScript

    sendData '/api/Tasks', { description: "new task" }

http://api.jquery.com/queue/

The queue iteself

This part is also simple, seeing how the hard work in creating a jQuery .ajaxQueue() method has already been done by gnarf, and here’s the blog post outlining the code. This came out of a great stackoverflow answer and this one.

Except one modification

The .then( next, next ) call was replaced with a failure case, in production code it’s likely to be a silent failure because there’s an error handling function higher up in the call chain that will report the problem to the user (no need for repeating the message).

    function doRequest( next ) {

        fail = function () { console.log('cannot continue to process queue after an error');

        jqXHR = $.ajax( ajaxOpts )
            .done( dfd.resolve )
            .fail( dfd.reject )
            .then( next, fail /*was next*/ );
    }

An added benefit here is not just around safety for the error case, but this queue approach ensures important user actions will get dispatched and arrive in a correct order.

Example

Scenario
1. Create a Task.
2. Update task details
3. Add Sub Task
4. Edit Sub Task [Fails]
5. Some other action (possibly related to the sub task)
6. 7. 8. 9. all same as 5.

At step 4, it fails, because something prevented the sub task being added. But before Task 4 failed, the user also issued action 5 very quickly. Step 5 is what the above code is preventing from running because we’re not sure what the impacts may be.

Before I release some Unit Tests to demonstrate this. I have a crude annotation on the Chrome Developer tools console output. The proof is lack of calls to ‘doneCb‘ after the error. Note the 500 error, then the 2 error messages that follow.

Ajax Queue Drop

Chrome debug output showing the error output.

Queues, Deferred and Promises

It’s beyond the scope of what I wanted to talk about here, but the jQuery.ajax wrapper jQuery.ajaxQueue makes use of Deferred, Deffered.then() and Promises, they’re worth looking into to gain a detailed understanding. Some reading about the queue itself.

Conclusion

So now a user can click to their hearts content on a variety of partially related actions on a page, having each fire off an ajax() request. If something goes wrong they can be alerted, and you can save a flood of subsequent errors happening.