I have built a simple wish list app in Tornado. The user adds URL to the product and the app keeps tracking its price. The flow is simple, the user logs in, there is a form and user pastes/enters the url in the form and clicks submit. This makes a post request to my server and that url will be added to database. 

For submit I am using ajax. So, it submits the request and refreshes the wishlist table in the page. However as this takes time, the users think the app is not working and tend to press 'submit' multiple times. It takes time, as my server verifies the URL, fetches its price, image and other details. 

During initial stages, I was talking directly to Tornado server. When I press submit button multiple times, Tornado would add it only once. I don't know how it managed to ignore same requests or how it figured out its same request, which is being processed. Since it never occurred, I never thought about it. 

Now there are four instances of Tornado are running behind a Nginx server. So I guess Nginx is passing the request to different tornado instances when multiple times submit is pressed. 

So how do I avoid this? 

* I could create a local storage in browser for every session and maintain list of URLs. When submit is pressed and if URL is already present in the list, then don't send the request. And I would destroy this storage whenever tab is closed.
* disable submit button once the url is submitted and till it receives reply from the server
* give a facebook style notification when the submit is pressed and hope user does not press submit again.
* configure nginx load balancer to work on ip-hash mode. so that the user always gets to served by same instance of Tornado
* may be configure nginx somehow that it ignores same POST requests as single instance of Tornado was doing earlier?

Here's the code in question (not sure if it actually matters): 

```
class ProductsHandler(BaseHandler):
    @tornado.web.authenticated
    def get(self):
        # ...
        # ...

    def post(self):
        user_email = self.get_secure_cookie('trakr')
        user_db = self.application.db.users
        product_db = self.application.db.products
        product_url = self.get_argument('product-url', None)
        if not product_url:
            self.redirect('/products')
            return

        vendor, url = utils.get_vendor(product_url)

        if not vendor:
            self.redirect('/products')
            return

        # this is where it checks whether the URL is already present in DB or not
        product_doc = product_db.find_one({'url': url})

        if not product_doc:
            # ...
            # ...            
            product_url, product_name, product_img_url, product_price = vendor_func_map[vendor_id](url)

            product_id = str(product_db.insert({'vendor_name': vendor_name,
                'vendor_id': vendor_id, 
                'name': product_name, 'url': url,
                'img_url': upload_to_imgur(product_img_url), 
                'price': product_price
                # ...
                # ...
                }))
        else:
            product_id = product_doc['_id']

        # add this product to users db
        # ...
        self.redirect('/products')

```

and jquery code for ajax: 

```
<script type="text/javascript">
    $(document).ready(function(){
        $("#product-add-form").on('submit',function(){
            var product_url = $("#product-url").val();
            console.log(product_url)
            var dataString = 'product-url='+ product_url
            $.ajax({
                type: "POST",
                url: "products",
                data: dataString,
                success: function() {
                    $('#product-table-div').load("/products #product-table-div")
                }
            });
        return false;
        });
    });
</script>

```

The HTML form:

```
<div id="product-add">
    <form action="/products" method="post" id="product-add-form">
        <fieldset>
            <label for="product-url">Product-Url</label>
            <input class="text-input" id="product-url" name="product-url" tabindex="1" type="text" value="">
        </fieldset>
        <div id="form_btn">
            <input id="prodadd-btn" class="btn btn-blue" type="submit" value="Submit" tabindex="3">
        </div>
    </form>
</div>

```