Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have a mobile app built using jquerymobile, PhoneGap and some custom CSS and JavaScript. The data objects are received in JSON and used to display different forms to the user. For example

{ id: 1, type: personal_details, question_1: "First name", question_2: "Last name" },
{ id: 2, type: work_details, question_1: "Occupation", question_2: "Experience" }

The user fills out these forms and sends the data back to a .NET application. Things work great when there is a good 3G connection but that is not always the case.

As each form is sent there is a danger that not all the forms will make it back together. In our example the personal details could be sent first, the connection is lost and the work details are left on the mobile device or lost on the network either of which frustrates my users.

What is the best strategy to handle and recover elegantly from network failures? Relying on the HTTP response codes doesn't seem to be working. E.g.

for ( form in forms ) {
    $.ajax({
        url: 'http://ac.me',
        data: form,
        success: function (){
            // delete from localStorage
        },
        error: function (){
            // show error message 'try again later'
        }
    });
}

The request can fail and the error function is never called. The alternative I see is sending all the forms in one JSON string but I am concerned about the performance implications of SQL server processing many short requests or fewer longer requests.

share|improve this question
add comment

1 Answer 1

up vote 2 down vote accepted

You're actually probably better off sending them all at once.

HTTP Requests are Expensive You need to remember that the act of making HTTP requests are, generally speaking, expensive. It's why you're supposed to merge your JavaScript into one file and make sprites for web sites.

Why are they expensive? And why does that matter even on a mobile application (even if, for the sake of argument, you're doing it natively)? Because it's the act of making the connection itself that makes it expensive. To open an HTTP connection, the client and the server go through a number of steps:

  1. DNS lookup. Is the server actually there? Can the client connect to it?
  2. SYN It is? Great! Start the handshake transaction (this is known as a "SYN" packet).
  3. SYN-ACK The server responds with the next step of the handshake transaction, known as a "SYN-ACK" packet.
  4. ACK The client responds again, with the third, and final step of the handshake. If all three steps are successful, then the connection is established. Now, we can actually get to our request.
  5. Send the request. This is where your data is actually getting sent.
  6. Wait for response. The server has to do something with request, which takes time, especially if a database or heavy calculations are involved.
  7. Receive Response The server sends back the response. This takes time based on the response size and connection integrity, just like the send request step.
  8. Load The client now has to do something with the information it got back from the server. Usually, it's rendering it to an output device, or triggering another event.
  9. FIN The client sends a "FIN" packet that closes the HTTP connection

(Check out this breakdown on the anatomy of an HTTP connection for more information.)

HTTP Requests Have Many Network-Based Failure Points Take a look again at the above list of steps that a transaction goes through. Six of the 9 steps will cause the connection to fail and your data to be lost if the network connection is dropped. That's a lot of failure points. You repeat those failure points every time you make an HTTP request. So, the more times you make the request, the more chances you have of a request failing due to network issues.

JSON Objects Aren't That Big JSON objects, being only text, are quite tiny when done properly. They can get pretty large, but you'd have to be sending a ton of data (most likely more data than you actually need and can probably filter down, such as search results with too vague a search term) to do so. Compared to the cost of making the HTTP connection, you have to get pretty large to offset it with too much JSON data.

JavaScript Gets No Response From Dropped Connections This is why your "error" function is not being called on a dropped connection (an "error" response is still a response from the server). JavaScript will wait indefinitely, unless it's told otherwise, for a response. If the network connection drops, JS isn't aware of it, and will continue to wait for a response that never comes. Your best bet for this issue is to set a timeout mechanism and retry the connection if the previous one times out.

HTTP Requests Have Nothing to do with SQL Server You should have an application layer, which exposes an API to your client, between your client and SQL Server. As such, you can format the database requests in a way that makes sense for it, regardless of what you do on the client side.

share|improve this answer
    
Thanks for the great answer. Setting a timeout and retrying could be problematic since most of the requests generate data stored on the server. Data duplication is another headache. I think I am going to try sending the data in one JSON object. Thanks :-) –  Peter Jan 10 '13 at 9:08
    
I see that you have some experience with Titanium and I assume on mobile devices on 3G networks. I tried doing a check for network quality e.g. if network > 2G but I had to roll back that release because it was always false! Do you do a network check and if so what kind? –  Peter Jan 10 '13 at 9:13
    
It's been a while since I developed on that platform, but I think we just checked for the existence of a network connection. The problem with cellular connections is that you don't always get any kind of warning before it drops. One moment it can be full-signal 4G, and the next, you've found yourself in a complete dead zone, without even voice signal. From a developer standpoint, you just have to be prepared to handle it gracefully. –  Shauna Jan 10 '13 at 13:25
    
One way to prevent data duplication may be to include some kind of transaction ID (probably time-based, so you don't get duplicate IDs), that the client holds until it receives a response from the server. The server stores this ID in the database (or a transient database, such as Redis), and if it matches something already in the server, it does an update instead of an insert. –  Shauna Jan 10 '13 at 13:27
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.