commit/galaxy-central: carlfeberhard: History panel: fix race condition when setting updater
1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/4dc1714a5a0a/ Changeset: 4dc1714a5a0a User: carlfeberhard Date: 2013-09-26 18:38:18 Summary: History panel: fix race condition when setting updater Affected #: 2 files diff -r a7e3721795d6c480d4e116f1054235450102d725 -r 4dc1714a5a0a9f2dde02dea061eb45b0aae1e08d static/scripts/mvc/history/history-model.js --- a/static/scripts/mvc/history/history-model.js +++ b/static/scripts/mvc/history/history-model.js @@ -49,6 +49,8 @@ /** HDACollection of the HDAs contained in this history. */ this.hdas = new HDACollection(); + this.updateTimeoutId = null; + // if we've got hdas passed in the constructor, load them and set up updates if needed if( initialHdas && _.isArray( initialHdas ) ){ this.hdas.add( initialHdas ); @@ -63,11 +65,7 @@ // then: refresh the panel this.hdas.bind( 'state:ready', function( hda, newState, oldState ){ if( hda.get( 'force_history_refresh' ) ){ - //TODO: could poll jobs here... - var history = this; - setTimeout( function(){ - history.stateUpdater(); - }, History.UPDATE_DELAY ); + this.updateAfterDelay(); } }, this ); @@ -87,13 +85,21 @@ }); }, + updateAfterDelay : function(){ + var history = this; + this.updateTimeoutId = setTimeout( function(){ + history.stateUpdater(); + }, History.UPDATE_DELAY ); + return this.updateTimeoutId; + }, + // get the history's state from it's cummulative ds states, delay + update if needed // events: ready checkForUpdates : function(){ // get overall History state from collection, run updater if History has running/queued hdas // boiling it down on the client to running/not if( this.hdas.running().length ){ - this.stateUpdater(); + this.updateAfterDelay(); } else { this.trigger( 'ready' ); @@ -105,6 +111,7 @@ // set up to run this again in some interval of time // events: ready stateUpdater : function(){ + //TODO: we need to get states from one location: history_contents (right now it's both history and contents) var history = this, oldState = this.get( 'state' ), // state ids is a map of every possible hda state, each containing a list of ids for hdas in that state @@ -133,19 +140,28 @@ // send the changed ids (if any) to dataset collection to have them fetch their own model changes if( changedIds.length ){ - history.fetchHdaUpdates( changedIds ); + history.fetchHdaUpdates( changedIds ) + .done( function(){ + furtherUpdatesOrReady( history ); + }); + } else { + furtherUpdatesOrReady( history ); } - // set up to keep pulling if this history in run/queue state - if( ( history.get( 'state' ) === HistoryDatasetAssociation.STATES.RUNNING ) - || ( history.get( 'state' ) === HistoryDatasetAssociation.STATES.QUEUED ) ){ - setTimeout( function(){ - history.stateUpdater(); - }, History.UPDATE_DELAY ); + function furtherUpdatesOrReady( history ){ + var timeout; + // set up to keep pulling if this history in run/queue state + if( ( history.get( 'state' ) === HistoryDatasetAssociation.STATES.RUNNING ) + || ( history.get( 'state' ) === HistoryDatasetAssociation.STATES.QUEUED ) ){ + //|| ( history.hdas.running() ) ){ + timeout = history.updateAfterDelay(); - // otherwise, we're now in a 'ready' state (no hdas running) - } else { - history.trigger( 'ready' ); + // otherwise, we're now in a 'ready' state (no hdas running) + } else { + this.updateTimeoutId = null; + history.trigger( 'ready' ); + } + return timeout; } }).error( function( xhr, status, error ){ @@ -176,8 +192,8 @@ */ fetchHdaUpdates : function( hdaIds ){ //TODO:?? move to collection? still need proper url - var history = this; - jQuery.ajax({ + var history = this, + xhr = jQuery.ajax({ url : this.url() + '/contents?' + jQuery.param({ ids : hdaIds.join(',') }), /** @@ -218,6 +234,7 @@ history.updateHdas( hdaDataList ); } }); + return xhr; }, /** Update the models in the hdas collection from the data given. diff -r a7e3721795d6c480d4e116f1054235450102d725 -r 4dc1714a5a0a9f2dde02dea061eb45b0aae1e08d static/scripts/packed/mvc/history/history-model.js --- a/static/scripts/packed/mvc/history/history-model.js +++ b/static/scripts/packed/mvc/history/history-model.js @@ -1,1 +1,1 @@ -var History=Backbone.Model.extend(LoggableMixin).extend({defaults:{id:null,name:"Unnamed History",state:"new",diskSize:0,deleted:false},urlRoot:"api/histories/",url:function(){return this.urlRoot+this.get("id")},initialize:function(b,c,a){a=a||null;this.log(this+".initialize:",b,c);this.hdas=new HDACollection();if(c&&_.isArray(c)){this.hdas.add(c);this.checkForUpdates();if(this.hdas.length>0){this.updateDisplayApplications()}}this.hdas.bind("state:ready",function(e,g,d){if(e.get("force_history_refresh")){var f=this;setTimeout(function(){f.stateUpdater()},History.UPDATE_DELAY)}},this);if(this.logger){this.bind("all",function(d){this.log(this+"",arguments)},this)}},hdaIdsFromStateIds:function(){return _.reduce(_.values(this.get("state_ids")),function(b,a){return b.concat(a)})},checkForUpdates:function(){if(this.hdas.running().length){this.stateUpdater()}else{this.trigger("ready")}return this},stateUpdater:function(){var c=this,a=this.get("state"),b=this.get("state_ids");jQuery.ajax("api/histories/"+this.get("id")).success(function(d){c.set(d);c.log("current history state:",c.get("state"),"(was)",a,"new size:",c.get("nice_size"));var e=[];_.each(_.keys(d.state_ids),function(g){var f=_.difference(d.state_ids[g],b[g]);e=e.concat(f)});if(e.length){c.fetchHdaUpdates(e)}if((c.get("state")===HistoryDatasetAssociation.STATES.RUNNING)||(c.get("state")===HistoryDatasetAssociation.STATES.QUEUED)){setTimeout(function(){c.stateUpdater()},History.UPDATE_DELAY)}else{c.trigger("ready")}}).error(function(g,d,e){if(g.status===502){setTimeout(function(){c.log("Bad Gateway error. Retrying...");c.stateUpdater()},History.UPDATE_DELAY)}else{if(!((g.readyState===0)&&(g.status===0))){c.log("stateUpdater error:",e,"responseText:",g.responseText);var f=_l("An error occurred while getting updates from the server.")+" "+_l("Please contact a Galaxy administrator if the problem persists.");c.trigger("error",f,g,d,e)}}})},fetchHdaUpdates:function(b){var a=this;jQuery.ajax({url:this.url()+"/contents?"+jQuery.param({ids:b.join(",")}),error:function(h,c,d){if((h.readyState===0)&&(h.status===0)){return}var f=JSON.parse(h.responseText);if(_.isArray(f)){var e=_.groupBy(f,function(i){if(_.has(i,"error")){return"errored"}return"ok"});a.log("fetched, errored datasets:",e.errored);a.updateHdas(f)}else{a.log("Error updating hdas from api history contents",b,h,c,d,f);var g=_l("An error occurred while getting dataset details from the server.")+" "+_l("Please contact a Galaxy administrator if the problem persists.");a.trigger("error",g,h,c,d)}},success:function(d,c,e){a.log(a+".fetchHdaUpdates, success:",c,e);a.updateHdas(d)}})},updateHdas:function(a){var c=this,b=[];c.log(c+".updateHdas:",a);_.each(a,function(e,f){var d=c.hdas.get(e.id);if(d){c.log("found existing model in list for id "+e.id+", updating...:");d.set(e)}else{c.log("NO existing model for id "+e.id+", creating...:");b.push(e)}});if(b.length){c.addHdas(b)}},addHdas:function(a){var b=this;_.each(a,function(c,d){var e=b.hdas.hidToCollectionIndex(c.hid);c.history_id=b.get("id");b.hdas.add(new HistoryDatasetAssociation(c),{at:e,silent:true})});b.hdas.trigger("add",a)},updateDisplayApplications:function(a){this.log(this+"updateDisplayApplications:",a);var c=this,b=(a&&_.isArray(a))?({hda_ids:a.join(",")}):({});c.log(this+": fetching display application data");jQuery.ajax("history/get_display_application_links",{data:b,success:function(f,d,e){_.each(f,function(h){var g=c.hdas.get(h.id);if(g){g.set(h)}})},error:function(g,d,e){if(!((g.readyState===0)&&(g.status===0))){c.log("Error fetching display applications:",a,g,d,e);var f=_l("An error occurred while getting display applications from the server.")+" "+_l("Please contact a Galaxy administrator if the problem persists.");c.trigger("error",f,g,d,e)}}})},toString:function(){var a=(this.get("name"))?(","+this.get("name")):("");return"History("+this.get("id")+a+")"}});History.UPDATE_DELAY=4000;var HistoryCollection=Backbone.Collection.extend(LoggableMixin).extend({model:History,urlRoot:"api/histories"}); \ No newline at end of file +var History=Backbone.Model.extend(LoggableMixin).extend({defaults:{id:null,name:"Unnamed History",state:"new",diskSize:0,deleted:false},urlRoot:"api/histories/",url:function(){return this.urlRoot+this.get("id")},initialize:function(b,c,a){a=a||null;this.log(this+".initialize:",b,c);this.hdas=new HDACollection();this.updateTimeoutId=null;if(c&&_.isArray(c)){this.hdas.add(c);this.checkForUpdates();if(this.hdas.length>0){this.updateDisplayApplications()}}this.hdas.bind("state:ready",function(e,f,d){if(e.get("force_history_refresh")){this.updateAfterDelay()}},this);if(this.logger){this.bind("all",function(d){this.log(this+"",arguments)},this)}},hdaIdsFromStateIds:function(){return _.reduce(_.values(this.get("state_ids")),function(b,a){return b.concat(a)})},updateAfterDelay:function(){var a=this;this.updateTimeoutId=setTimeout(function(){a.stateUpdater()},History.UPDATE_DELAY);return this.updateTimeoutId},checkForUpdates:function(){if(this.hdas.running().length){this.updateAfterDelay()}else{this.trigger("ready")}return this},stateUpdater:function(){var c=this,a=this.get("state"),b=this.get("state_ids");jQuery.ajax("api/histories/"+this.get("id")).success(function(d){c.set(d);c.log("current history state:",c.get("state"),"(was)",a,"new size:",c.get("nice_size"));var f=[];_.each(_.keys(d.state_ids),function(h){var g=_.difference(d.state_ids[h],b[h]);f=f.concat(g)});if(f.length){c.fetchHdaUpdates(f).done(function(){e(c)})}else{e(c)}function e(h){var g;if((h.get("state")===HistoryDatasetAssociation.STATES.RUNNING)||(h.get("state")===HistoryDatasetAssociation.STATES.QUEUED)){g=h.updateAfterDelay()}else{this.updateTimeoutId=null;h.trigger("ready")}return g}}).error(function(g,d,e){if(g.status===502){setTimeout(function(){c.log("Bad Gateway error. Retrying...");c.stateUpdater()},History.UPDATE_DELAY)}else{if(!((g.readyState===0)&&(g.status===0))){c.log("stateUpdater error:",e,"responseText:",g.responseText);var f=_l("An error occurred while getting updates from the server.")+" "+_l("Please contact a Galaxy administrator if the problem persists.");c.trigger("error",f,g,d,e)}}})},fetchHdaUpdates:function(c){var a=this,b=jQuery.ajax({url:this.url()+"/contents?"+jQuery.param({ids:c.join(",")}),error:function(i,d,e){if((i.readyState===0)&&(i.status===0)){return}var g=JSON.parse(i.responseText);if(_.isArray(g)){var f=_.groupBy(g,function(j){if(_.has(j,"error")){return"errored"}return"ok"});a.log("fetched, errored datasets:",f.errored);a.updateHdas(g)}else{a.log("Error updating hdas from api history contents",c,i,d,e,g);var h=_l("An error occurred while getting dataset details from the server.")+" "+_l("Please contact a Galaxy administrator if the problem persists.");a.trigger("error",h,i,d,e)}},success:function(e,d,f){a.log(a+".fetchHdaUpdates, success:",d,f);a.updateHdas(e)}});return b},updateHdas:function(a){var c=this,b=[];c.log(c+".updateHdas:",a);_.each(a,function(e,f){var d=c.hdas.get(e.id);if(d){c.log("found existing model in list for id "+e.id+", updating...:");d.set(e)}else{c.log("NO existing model for id "+e.id+", creating...:");b.push(e)}});if(b.length){c.addHdas(b)}},addHdas:function(a){var b=this;_.each(a,function(c,d){var e=b.hdas.hidToCollectionIndex(c.hid);c.history_id=b.get("id");b.hdas.add(new HistoryDatasetAssociation(c),{at:e,silent:true})});b.hdas.trigger("add",a)},updateDisplayApplications:function(a){this.log(this+"updateDisplayApplications:",a);var c=this,b=(a&&_.isArray(a))?({hda_ids:a.join(",")}):({});c.log(this+": fetching display application data");jQuery.ajax("history/get_display_application_links",{data:b,success:function(f,d,e){_.each(f,function(h){var g=c.hdas.get(h.id);if(g){g.set(h)}})},error:function(g,d,e){if(!((g.readyState===0)&&(g.status===0))){c.log("Error fetching display applications:",a,g,d,e);var f=_l("An error occurred while getting display applications from the server.")+" "+_l("Please contact a Galaxy administrator if the problem persists.");c.trigger("error",f,g,d,e)}}})},toString:function(){var a=(this.get("name"))?(","+this.get("name")):("");return"History("+this.get("id")+a+")"}});History.UPDATE_DELAY=4000;var HistoryCollection=Backbone.Collection.extend(LoggableMixin).extend({model:History,urlRoot:"api/histories"}); \ No newline at end of file Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.
participants (1)
-
commits-noreply@bitbucket.org