# Robust xhr command queue

**URL:** <https://www.ruby-forum.com/t/robust-xhr-command-queue/149967>\
**Category:** Rails\
**Created:** [October 1, 2008, 8:52pm UTC](https://www.ruby-forum.com/t/robust-xhr-command-queue/149967 "2008-10-01T20:52:05Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![darren](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e9a140/32.png) [@darren](https://www.ruby-forum.com/u/darren)\
**Post date:** [October 1, 2008, 8:52pm UTC](https://www.ruby-forum.com/t/robust-xhr-command-queue/149967/1 "2008-10-01T20:52:05Z")

</div>

Hi,

I’d like to implement a robust command queue for an ajaxy web app. I  
was wonder if anyone would be able to feed me back any constructive  
criticism that comes to mind on this.

The problem in my mind is that if an xhr request is dropped by the  
network (or never makes it out of the browser’s machine etc), I want  
the server to ignore further xhr commands until it turns up (if it’s  
truly lost, the user sees that a box on the page is still displaying  
‘Syncing …’, so knows to reload the page manually).

One approach I’ve thought of involves each xhr including a ‘command  
ID’ param, a simple incrementing integer. Then, server-side there is a  
queue of incoming commands. If a sent xhr is dropped by the network,  
the server will then detect the missing ID and will queue up all  
incoming commands until the missing command turns up, or until the  
user refreshes the page and the command ID is reset.

This is how it would break down:

1. user loads page, session[:cmdID] = 0

2. user initiates xhr command A, params[:cmdID] = 0

3. server receives A, sets session[:cmdID] = 1, sends response

4. user initiates xhr command B, params[:cmdID] = 1

5. user initiates xhr command C, params[:cmdID] = 2

6. server recieves C, but deduces there was a missing command because  
an xhr with params[:cmdID] == 1 was never received

7. server queues C and waits for B to turn up.

Meanwhile clientside javascript knows the response to B was never  
received, so clearly shows this in a status bar (“Syncing …”). Any  
links exiting this page are disabled until all xhr requests have been  
resolved. Or, if the user can hit Refresh on their browser, so the  
client view is manually synced.

Probably there are some further complexities (what happens if the  
response to (3) is never received by the client? Perhaps just make  
sure that any potentially conflicting actions are disabled clientside  
until the response is received)

- maybe this is the starting point. What do y’all think?

[ nb I think this is really where Google Gears would shine? But I  
definitely can’t rely on the userbase installing a plugin! ]

Thanks!  
Darren

---

<div class="post-metadata">

**Author:** ![darren](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e9a140/32.png) [@darren](https://www.ruby-forum.com/u/darren)\
**Post date:** [October 1, 2008, 8:56pm UTC](https://www.ruby-forum.com/t/robust-xhr-command-queue/149967/2 "2008-10-01T20:56:48Z")

</div>

Hi,

more potential edge cases than actual criticism, but:

- Watch out for session race conditions (likely to happen if there is  
overlap in the processing of the requests).

- What do you do if requests are processed in a different order from  
the order in which they where sent (eg because the second request is  
routed to a mongrel that is free but the first one is routed to a  
mongrel that is processing a request and has to wait) ?

- Watch out for users with more than one tab/browser window open onto  
your website

Fred

---

<div class="post-metadata">

**Author:** ![darren](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e9a140/32.png) [@darren](https://www.ruby-forum.com/u/darren)\
**Post date:** [October 15, 2008, 6:14am UTC](https://www.ruby-forum.com/t/robust-xhr-command-queue/149967/3 "2008-10-15T06:14:17Z")

</div>

hm,

yeah … does seem to be very hacky - worthy of some serious  
programming.

On Oct 1, 11:56 am, Frederick C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
