0

I'm using django development server on windows 8.1 64 bit. I'm also using Tastypie. The mysql version is: 5.5 (x86).

The problem I'm facing is that various queries randomly hangs. I'm using AJAX at the client, but it also happens when I'm using the django admin. I saw that all similar questions relates to chrome issue. But it happens also on Firefox. My database is mysql. Lately I installed SSD drive so all my development code and database is on that SSD (not that I think this should make any difference)

Here is an example of few queries as seen in the Firebug. in this case the 4th hangs (randomly, sometimes it is a different one)

GET id=1">http://127.0.0.1:8000/api/v1/financialmodel/?user_id=1 200 OK 1.33s jquery....min.js GET id=1">http://127.0.0.1:8000/api/v1/strategy/?user_id=1 200 OK 1.35s jquery....min.js (line 6) GET id=1">http://127.0.0.1:8000/api/v1/currency/?user_id=1 200 OK 1.4s jquery....min.js (line 6) the next query get stuck (but this is random sometime it is another query) GET id=1">http://127.0.0.1:8000/api/v1/account/?user_id=1 jquery....min.js (line 6) GET id=1">http://127.0.0.1:8000/api/v1/bankbranch/?user_id=1 200 OK 2.62s

I tried running the server with:

runserver with --nothread (or without)

did not change anything.

I tried installing //github.com/ashchristopher/django-concurrent-server thinking this might help, but same thing still random hangs on various queries.

If I pause the server using the debugger in the APTANA IDE, I find that the server is at:

SocketServer.py line 155

def _eintr_retry(func, *args):
    """restart a system call interrupted by EINTR"""
    while True:
        try:
            return func(*args)
        except (OSError, select.error) as e:
            if e.args[0] != errno.EINTR:
                raise

Any ideas? Thanks a lot!

Here is the line in the Ajax code from jquery-2.0.3

// Do send the request

// This may raise an exception which is actually

// handled in jQuery.ajax (so no try/catch here)

                xhr.send( options.hasContent && 
options.data || null );
            },

            abort: function() {

                if ( callback ) {

                    callback();

                }

            }

        };

    }

});

Here is a function that loads a ui tree:

function loadAccountsTree() {
    $.getJSON("/api/v1/account/?user__id=" + userid, function(json) {
        // Extracting the required JSON structure from the entire response
        var tree = json.objects[0];
        $("#accounts-tree").jstree({
            "sort" : function() {
            },
            "json_data" : {
                "data" : tree
            },
            "types" : {
                "max_children" : 1,
                "types" : {
                    // Account type
                    "default" : {
                        "valid_children" : "none"
                    },
                    "folder" : {
                        "valid_children" : ["default", "folder"]
                    }
                }
            },
            "hotkeys" : {
                "return" : function() {
                    var hovered = $('#accounts-tree .jstree-hovered');
                    if (hovered.length) {
                        $("#accounts-tree").jstree("deselect_all");
                        $("#accounts-tree").jstree("select_node", hovered);
                    }
                }
            },
            "ui" : {
                select_multiple_modifier : false
            },
            "contextmenu" : {
                // Select node when right-clicking
                "select_node" : true,
                items : {// Could be a function that should return an object like this one
                    "ccp" : false,
                    "create" : {
                        "separator_before" : false,
                        "separator_after" : true,
                        "label" : "Create",
                        "action" : false,
                        "submenu" : {
                            "create_file" : {
                                "seperator_before" : false,
                                "seperator_after" : false,
                                "label" : "Account",
                                action : function(obj) {
                                    this.create(obj, "last", {
                                        "attr" : {
                                            "rel" : "default"
                                        }
                                    });
                                }
                            },
                            "create_folder" : {
                                "seperator_before" : false,
                                "seperator_after" : false,
                                "label" : "Folder",
                                action : function(obj) {
                                    this.create(obj, "last", {
                                        "attr" : {
                                            "rel" : "folder"
                                        }
                                    });
                                }
                            } // End of "create_folder" contextmenu function
                        }
                    }
                }
            },
            "plugins" : ["themes", "json_data", "ui", "hotkeys", "crrm", "dnd", "contextmenu", "types"]
        }).bind("before.jstree", function(e, data) {
            if (data.func === "remove") {
                var nodes = data.inst._get_node(null, true);
                for (var i = 0; i < nodes.length; i++) {
                    var node = nodes[i];
                    var nodeName = $(node).find('> a').text().substring(1);
                    if ($(node).find('> ul').length) {
                        alert('You need to delete all folders and accounts inside ' + nodeName + ' before deleting it.');
                        e.stopImmediatePropagation();
                        return false;
                    } else if (!confirm("Are you sure you want to delete " + nodeName + " ?")) {
                        e.stopImmediatePropagation();
                        return false;
                    }
                }
            }
        }).bind("loaded.jstree", function(event, data) {
            // Selecting top account
            data.inst.select_node('> ul > li:first');
            // Loading all assets for top account
            loadAccountAssets($("#accounts-tree > ul:first > li:first").attr("id"));
            loadCommissions($("#accounts-tree > ul:first > li:first").attr("id"));
        }).bind("create.jstree", function(e, data) {
            var newNode = data.rslt.obj;
            var verified = true;
            $(newNode).siblings().each(function(idx, listItem) {
                var siblingNode = $(listItem);
                if (newNode.attr("rel") !== siblingNode.attr("rel")) {
                    verified = false;
                    return false;
                }
            });
            var isFolder;
            if (data.rslt.obj.attr("rel") == 'default') {
                isFolder = 'false';
            } else {
                isFolder = 'true';
            }
            if (verified) {
                $.ajax({
                    type : 'POST',
                    // make sure you respect the same origin policy with this url:
                    // http://en.wikipedia.org/wiki/Same_origin_policy
                    url : '/api/v1/account/',
                    data : JSON.stringify({
                        'folder' : isFolder,
                        'user' : '/api/v1/user/' + userid + '/',
                        'parent' : '/api/v1/account/' + data.rslt.parent.attr("id") + '/',
                        'name' : data.rslt.name,
                        'type' : data.rslt.obj.attr("rel")
                    }),
                    contentType : "application/json",
                    dataType : 'json',
                    processData : false,
                    success : function(r) {
                        data.rslt.obj.attr("id", r.id);
                    },
                    error : function(xhr, textStatus, error) {
                        loadAccountsTree();
                        logErrors(xhr, textStatus, error);
                    }
                });
            } else {
                alert("Folders can contain either folders or accounts, not both at a time.");
                $(newNode).prev().addClass("jstree-last");
                $(newNode).remove();
            }
        }).bind("rename.jstree", function(e, data) {
            $.ajax({
                type : 'PATCH',
                url : '/api/v1/account/' + data.rslt.obj.attr("id") + '/',
                data : JSON.stringify({
                    "name" : data.rslt.new_name
                }),
                dataType : 'json',
                contentType : 'application/json',
                error : function(xhr, textStatus, error) {
                    loadAccountsTree();
                    logErrors(xhr, textStatus, error);
                }
            });
        }).bind("remove.jstree", function(e, data) {
            $.ajax({
                type : 'DELETE',
                url : '/api/v1/account/' + data.rslt.obj.attr("id") + '/'
            });
        }).bind("select_node.jstree", function(event, data) {
            var currentNode = data.rslt.obj;
            var ui_currency = ($('#usd').hasClass('active')) ? 'usd' : 'ils';
            var isFolder = currentNode.attr("rel") === "folder";
            if (isFolder) {
                $("#account-form").slideUp();
            } else {
                // The account is not a folder. Show account details and load its commissions.
                $("#account-form").slideDown();
                $("#account-name").attr("value", $(currentNode).text().substring(2));
                var bankId = $(currentNode).closest("li").data("bank_id");
                var accountBank = (bankId) ? bankId : "None";
                $("#bank").val(accountBank);
                $("#account-type").val($(currentNode).closest("li").data("account_type"));
                reloadAccountCommissions(currentNode.attr("id"));
            }
            reloadAccountAssets(isFolder, currentNode.attr("id"), ui_currency);
            var parents = currentNode.parents("li");
            var parentsList = currentNode.children("a").text().substring(1);
            parents.each(function(index) {
                parentsList = $(this).children("a").text().substring(1) + ' > ' + parentsList;
            });
            $("#account-title").text(currentNode.find("> a").text().substring(1) + " details");
            $("#account-breadcrumbs > p").text("Accounts: " + parentsList);
        }).bind("move_node.jstree", function(e, data) {
            data.rslt.o.each(function(i) {
                var valid = true;
                var currentNode = $(this);
                $(currentNode).siblings().each(function(idx, listItem) {
                    var siblingNode = $(listItem);
                    if (currentNode.attr("rel") !== siblingNode.attr("rel")) {
                        valid = false;
                        return false;
                    }
                });
                if (valid) {
                    $.ajax({
                        type : 'PATCH',
                        url : '/api/v1/account/' + currentNode.attr("id") + '/',
                        data : JSON.stringify({
                            "parent" : '/api/v1/account/' + data.rslt.np.attr("id") + '/'
                        }),
                        dataType : 'json',
                        contentType : 'application/json',
                        error : function(xhr, textStatus, error) {
                            loadAccountsTree();
                            logErrors(xhr, textStatus, error);
                        }
                    });
                } else {
                    $(data.rslt.op).append(currentNode);
                    $(currentNode).addClass("jstree-last");
                    alert("The parent folder can not contain folders and accounts at the same time.");
                }
            });
        });
    });
}

Here is the function that loads all the assets for the selected account into a grid (this grid sometimes stays "Loading...", when I check the server log 200 was sent back, but in the Firebug one of the queries never ends

function loadAccountAssets(accountid) {
    $("#pager-account-assets").empty();
    var ui_currency = ($('#usd').hasClass('active')) ? 'usd' : 'ils';
    $("#jqgrid-account-assets").empty().jqGrid({
        url : '/api/v1/assetgrid/?user__id=' + userid + '&account__id__in=' + accountid + '&ui_currency_code=' + ui_currency,
        datatype : 'json',
        ajaxGridOptions : {
            contentType : "application/json"
        },
        jsonReader : {
            repeatitems : false,
            id : "id"
        },
        colNames : ['Account', 'Place', 'Subtype', 'Issuer', 'Price linkage', 'Interest type', 'Return net', 'Return gross', 'Maturity term', 'Maturity date', 'Symbol', 'Update', 'Update hint', 'Value', 'Currency', 'Units', 'Price', 'Description', 'FinancialModel'],
        // 'Issuer', 'Price linkage', 'Interest type', 'Return net', 'Return gross', 'Maturity term', 'Maturity date', 'Financialmodel',
        colModel : [{
            name : 'Account',
            edittype : 'select',
            editoptions : {
                dataUrl : '/api/v1/account/?user__id=' + userid + '&folder=false',
                buildSelect : function(data) {
                    var response = $.parseJSON(data);
                    var s = '<select>';
                    $.each(response.objects, function(index, account) {
                        s += '<option value="' + account.resource_uri + '">' + account.data + '</option>';
                    });
                    return s + "</select>";
                }
            },
            stype : 'select'
        }, buildHiddenColumn('Place', 'place', true, false, 'resource_uri', 'name'), buildHiddenColumn('Subtype', 'subtype', true, false, 'resource_uri', 'name'), buildHiddenColumn('Issuer', 'issuer', true, false, 'resource_uri', 'name'), {
            name : 'price_linkage',
            hidden : true,
            editable : true,
            edittype : 'select',
            editoptions : {
                value : 'F:Foreign Currency;M:Madad;I:ILS'
            },
            stype : 'select',
            editrules : {
                edithidden : true
            }
        }, {
            name : 'Interest',
            hidden : true,
            editable : true,
            edittype : 'select',
            editoptions : {
                value : 'F:Fix;C:Changing;O:Other'
            },
            stype : 'select',
            editrules : {
                edithidden : true
            }
        }, {
            name : 'Return Net',
            editable : true,
            editrules : {
                edithidden : true
            },
            hidden : true,
            editoptions : {
                dataInit : function(element) {
                    $(element).attr("readonly", true);
                }
            }
        }, {
            name : 'Return Gross',
            editable : true,
            editrules : {
                edithidden : true
            },
            hidden : true,
            editoptions : {
                dataInit : function(element) {
                    $(element).attr("readonly", "readonly");
                }
            }
        }, {
            name : 'Maturity',
            hidden : true,
            editable : true,
            edittype : 'select',
            editoptions : {
                value : 'S:Short;M:Medium;L:Long'
            },
            stype : 'select',
            editrules : {
                edithidden : true
            }
        }, {
            name : 'MaturityDate',
            hidden : true,
            editable : true,
            formatter : "date",
            editoptions : {
                dataInit : function(el) {
                    setTimeout(function() {
                        $(el).datepicker({
                            dateFormat : "yy-mm-dd"
                        });
                    }, 200);
                }
            },
            formoptions : {
                rowpos : 1,
                colpos : 2
            },
            formatoptions : {
                newformat : "Y-m-d"
            },
            editrules : {
                edithidden : true
            }
        }, symbolColumn, {
            name : 'Update',
            edittype : 'select',
            editoptions : {
                value : 'A:Automatic;M:Manual'
            },
            formoptions : {
                rowpos : 2,
                colpos : 2
            },
            stype : 'select',
        }, {
            name : 'UpdHint',
            formoptions : {
                rowpos : 3,
                colpos : 2
            }
        }, {
            name : 'Value',
            width : 70,
            editable : false
        }, currencyColumn, {
            name : 'Units',
            width : 70,
            formoptions : {
                rowpos : 4,
                colpos : 2
            },
            editoptions : {
                dataInit : function(elem) {
                    setTimeout(function() {
                        // It must be an integer
                        $(elem).numeric(false, function() {
                            alert("Integers only");
                            this.value = "";
                            this.focus();
                        });
                    }, 100);
                }
            }
        }, {
            name : 'Price',
            width : 70,
            formoptions : {
                rowpos : 5,
                colpos : 2
            },
            editoptions : {
                dataInit : function(elem) {
                    setTimeout(function() {
                        $(elem).numeric();
                    }, 100);
                }
            }
        }, {
            name : 'Description',
            formoptions : {
                rowpos : 6,
                colpos : 2
            },
            width : 200
        }, {
            name : 'FinancialModel',
            edittype : 'select',
            formoptions : {
                rowpos : 7,
                colpos : 2
            },
            editoptions : {
                dataUrl : '/api/v1/financialmodel/?user__id=' + userid,
                buildSelect : function(data) {
                    var response = $.parseJSON(data);
                    var s = '<select><option value="">None</option>';
                    $.each(response.objects, function(index, financialmodel) {
                        s += '<option value="' + financialmodel.resource_uri + '">' + financialmodel.data + '</option>';
                    });
                    return s + "</select>";
                }
            },
            stype : 'select'
        }],
        cmTemplate : {
            editable : true,
            width : 100
        },
        ondblClickRow : function() {
            var rowid = $("#jqgrid-account-assets").getGridParam('selrow');
            $('#jqgrid-account-assets').jqGrid('editRow', rowid, {
                keys : true,
                dataType : 'json',
                url : '/api/v1/assetgrid/' + encodeURIComponent(rowid) + '/',
                mtype : 'PATCH'
            });
        },
        serializeRowData : function(data) {
            return serializeAssetData(data);
        },
        ajaxRowOptions : {
            contentType : "application/json"
        },
        width : 835,
        shrinkToFit : false,
        gridview : true,
        height : "auto",
        autoencode : true,
        loadonce : true,
        rowNum : 10,
        rowList : [10, 20, 30],
        pager : "#pager-account-assets",
        viewrecords : true,
    }).jqGrid("navGrid", "#pager-account-assets", {
        search : false,
        refresh : false
    },
    // edit options
    {
        closeAfterEdit : true,
        mtype : "PUT",
        serializeEditData : function(data) {
            return serializeAssetData(data);
        },
        onclickSubmit : function(params, postdata) {
            params.url = '/api/v1/assetgrid/' + encodeURIComponent(postdata[this.id + "_id"]) + '/';
        },
        ajaxEditOptions : {
            contentType : "application/json",
            dataType : "json"
        },
        afterSubmit : function(response, postdata) {
            $('#jqgrid-account-assets').setGridParam({
                datatype : 'json'
            }).trigger('reloadGrid');
            return [true, '', false];
        },
        beforeShowForm : function(form) {
            centerDialog($("#editmodjqgrid-account-assets"));
        }
    },
    // add options
    {
        closeAfterAdd : true,
        mtype : "POST",
        serializeEditData : function(data) {
            return serializeAssetData(data);
        },
        onclickSubmit : function(params, postdata) {
            params.url = '/api/v1/assetgrid/';
        },
        afterSubmit : function(response, postdata) {
            $('#jqgrid-account-assets').setGridParam({
                datatype : 'json'
            }).trigger('reloadGrid');
            return [true, ''];
        },
        ajaxEditOptions : {
            contentType : "application/json",
            dataType : "json"
        },
        beforeShowForm : function(form) {
            centerDialog($("#editmodjqgrid-account-assets"));
        }
    },
    // delete options
    {
        // Delete parameters
        mtype : "DELETE",
        serializeDelData : function() {
            return "";
        },
        onclickSubmit : function(params, postdata) {
            params.url = '/api/v1/assetgrid/' + encodeURIComponent(postdata) + '/';
        },
        beforeShowForm : function(form) {
            centerDialog($("#delmodjqgrid-account-assets"));
        },
        afterSubmit : function(response, postdata) {
            $('#jqgrid-account-assets').setGridParam({
                datatype : 'json'
            }).trigger('reloadGrid');
            return [true, ''];
        }
    });
}
Kara
  • 6,115
  • 16
  • 50
  • 57
Joe
  • 11
  • 3
  • Could you share your queries or you ajax calls? The problem is probably there... – yuvi Jan 10 '14 at 07:56
  • yuvi, I think you are right. Th eproblem is probably in the Ajax code. I counted the queries in the runserver log and and realized that the query which shown to be stuck in the firebug, got to the server and returned 200. for some reason the Ajax code is stuck. The call arrived from a jquery-2.0.3 line 7845. I included the relevant piece of code here. Since someone else is writing the client side, I probably have to get their help unless you have some clue. – Joe Jan 11 '14 at 11:35
  • I think I found a clue... it is in the jquery.jqGrid.js file. The following post http://stackoverflow.com/questions/1470333/jqgrid-stuck-on-loading talks about it. I have to check that – Joe Jan 11 '14 at 12:07
  • Can you share your django queries, and also the rest of the client side code? Even if you think everything is OK you might very well be missing something – yuvi Jan 11 '14 at 15:45
  • Thanks. I added the function that loads a tree with some account information. and also a function that loads a grid of assets for the selected account in the tree – Joe Jan 12 '14 at 11:12

1 Answers1

1

I have been using tastypie in my django project. That works very smoothly, I didn't have such issue. To debug this first make sure where the problem is. Does the request reach server, does database query take too much time, does database connection break and like that to know whether database causing problem or your django code or tastypie or ajax calls.

Development server log, I suppose you know already. paste it's output here so that we can get more understanding.

To check mysql log : follow How to see log files in MySQL?

You are using browser to call these api then install django-debug-toolbar, it will fetch some info. try curl also instead of browser :

curl http://127.0.0.1:8000/api/v1/account/?user_id=1

Also see this. http://django-tastypie.readthedocs.org/en/latest/debugging.html

P.S: I can't comment as I have low reputation as of now.

Community
  • 1
  • 1
Pradeep Sharma
  • 327
  • 4
  • 15
  • Thanks for the reply. Regarding the SQL log: I checked the sql server log. The query reached the SQL server correctly. also no errors on the sql.err file. on the browser I'm using FireBug, which shows the query that hangs nothing special besides it never ends (but each time it is a different query, this is why I think it is server related). I ran the same code on Linux (in my hosting service) and there it works fine. So it is windows related somehow. – Joe Jan 10 '14 at 16:32
  • Share your queries and your mysql version on windows. There have been some bugs in earlier mysql which behave similar to your situation. – Pradeep Sharma Jan 12 '14 at 07:54
  • I shared some of my queries. The mysql version is: 5.5 (x86), windows 8.1 64 bit. – Joe Jan 12 '14 at 11:17