[MERGE][FIX] web: fix race condition in BufferedDataset.
authorChristophe Simonis <chs@openerp.com>
Thu, 14 Nov 2013 14:26:39 +0000 (15:26 +0100)
committerChristophe Simonis <chs@openerp.com>
Thu, 14 Nov 2013 14:26:39 +0000 (15:26 +0100)
Backport of saas-2 commit 3867 nicolas.vanhoren@openerp.com-20131107112017-7omd01ocvnbzx9m6

lp bug: https://launchpad.net/bugs/1248531 fixed

bzr revid: chs@openerp.com-20131114142639-ng7wzfjwvvel2nhv

addons/web/static/src/js/data.js

index bb658a2..d497cf2 100644 (file)
@@ -761,6 +761,7 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({
         this._super.apply(this, arguments);
         this.reset_ids([]);
         this.last_default_get = {};
+        this.running_reads = [];
     },
     default_get: function(fields, options) {
         var self = this;
@@ -827,6 +828,9 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({
         this.to_write = [];
         this.cache = [];
         this.delete_all = false;
+        _.each(_.clone(this.running_reads), function(el) {
+            el.reject();
+        });
     },
     read_ids: function (ids, fields, options) {
         var self = this;
@@ -842,7 +846,6 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({
                     to_get.push(id);
             }
         });
-        var completion = $.Deferred();
         var return_records = function() {
             var records = _.map(ids, function(id) {
                 return _.extend({}, _.detect(self.cache, function(c) {return c.id === id;}).values, {"id": id});
@@ -877,10 +880,20 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({
                     }, 0);
                 });
             }
-            completion.resolve(records);
+            return $.when(records);
         };
         if(to_get.length > 0) {
-            var rpc_promise = this._super(to_get, fields, options).done(function(records) {
+            var def = $.Deferred();
+            self.running_reads.push(def);
+            def.always(function() {
+                self.running_reads = _.without(self.running_reads, def);
+            });
+            this._super(to_get, fields, options).then(function() {
+                def.resolve.apply(def, arguments);
+            }, function() {
+                def.reject.apply(def, arguments);
+            });
+            return def.then(function(records) {
                 _.each(records, function(record, index) {
                     var id = to_get[index];
                     var cached = _.detect(self.cache, function(x) {return x.id === id;});
@@ -891,13 +904,11 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({
                         cached.values = _.defaults(_.clone(cached.values), record);
                     }
                 });
-                return_records();
+                return return_records();
             });
-            $.when(rpc_promise).fail(function() {completion.reject();});
         } else {
-            return_records();
+            return return_records();
         }
-        return completion.promise();
     },
     /**
      * Invalidates caching of a record in the dataset to ensure the next read