PDA

View Full Version : Too Many Requests Issued When Updating Multiple Records in Restful Store



aleg
20 Jan 2011, 11:37 AM
Ext version tested:

Ext 3.3.1


Adapter used:

ext


css used:

only default ext-all.css




Browser versions tested against:

Safari 5


Operating System:

Mac OSX


Description:
Changing multiple records in a restful store simultaneously will issue (summation (n)) requests to the server, where n is the number of changed records. IE if you change 3 records in a restful store asynchronously this will issue 6 PUT requests to the server 3 for the first record change, 2 for the second record, and 1 for the third.

Test Case:



Ext.onReady(function(){

// define store
var store = new Ext.data.Store({
restful: true,
autoLoad: true,
writer: new Ext.data.JsonWriter({
encode: false
}),
reader: new Ext.data.JsonReader(),
proxy: new Ext.data.HttpProxy({
url: '/resources'
})
});

// watch proxy events
Ext.data.DataProxy.addListener('beforewrite', function(proxy, action, record) {
console.log("Before " + action, record.id);
});

// update first three records in store
store.on('load', function() {
Ext.each(store.getRange(0,2), function(r) {
r.set('confirmed', true);
});
}, undefined, {single: true});

});



Steps to reproduce the problem:

setup a backend route to supply your store with at least 3 resources with a `confirmed` property and metaData to describe them.
run above code


The result that was expected:

Three update requests sent to server (one for each resource modified)


The result that occurs instead:

Six update requests sent to server


Debugging already done:

none


Possible fix:

not provided

aleg
21 Jan 2011, 10:25 AM
Looks like a similar issue has been documented here (http://www.sencha.com/forum/showthread.php?93866-OPEN-702-RESTful-store-proxy-sends-multiple-HTTP-requests). The fix (hack) described does not seem to help in my case. Anybody have a solution?

aleg
21 Jan 2011, 1:58 PM
To further demonstrate the problem, here's the hack I'm using to to get around this shortcoming for the time being. I'm adding methods and event callbacks to the store to prevent multiple simultaneous requests getting sent to the server for each record. Seems to do the trick, but feels kludgy.


Ext.onReady(function(){

// define store
var store = new Ext.data.Store({
restful: true,
autoLoad: true,
writer: new Ext.data.JsonWriter({
encode: false
}),
reader: new Ext.data.JsonReader(),
proxy: new Ext.data.HttpProxy({
url: '/resources'
}),
_currentTransactions: {}
});

// extend store instance with helper transaction methods
Ext.apply(store, {
startTransaction: function(record) {
var transactions = this._currentTransactions,
encodedChanges = Ext.util.JSON.encode(record.getChanges());

transactions[record.id] = transactions[record.id] || [];
if (transactions[record.id].indexOf(encodedChanges) === -1) {
transactions[record.id].push(encodedChanges);
}
},

endTransaction: function(record) {
var transactions = this._currentTransactions,
encodedChanges = Ext.util.JSON.encode(record.getChanges());

if (transactions[record.id]) { transactions[record.id].pop(encodedChanges); }
},

hasActiveTransaction: function(record) {
var transactions = this._currentTransactions,
encodedChanges = Ext.util.JSON.encode(record.getChanges());

return transactions[record.id] ? transactions[record.id].indexOf(encodedChanges) !== -1 : false;
}
});

// events to record transactions and prevent duplicate requests
store.on('beforewrite', function(store, action, record) {
if (!store.hasActiveTransaction(record)) { return false; }
else { store.startTransaction(record); }
});
store.on('write', function(store, action, result, res, record) {
store.endTransaction(record);
});

// update first three records in store
store.on('load', function() {
Ext.each(store.getRange(0,2), function(r) {
r.set('confirmed', true);
});
}, undefined, {single: true});

});