details: http://www.bx.psu.edu/hg/galaxy/rev/3f407d489ade changeset: 2479:3f407d489ade user: James Taylor <james@jamestaylor.org> date: Fri May 22 14:46:17 2009 -0400 description: Performance improvements for large histories (both on database query and javascript) 5 file(s) affected in this change: lib/galaxy/datatypes/registry.py lib/galaxy/model/mapping.py lib/galaxy/web/controllers/root.py lib/galaxy/web/framework/__init__.py templates/root/history.mako diffs (243 lines): diff -r feb7438276fb -r 3f407d489ade lib/galaxy/datatypes/registry.py --- a/lib/galaxy/datatypes/registry.py Mon Jul 13 13:08:52 2009 -0400 +++ b/lib/galaxy/datatypes/registry.py Fri May 22 14:46:17 2009 -0400 @@ -211,7 +211,8 @@ builder = self.datatypes_by_extension[ext] except KeyError: builder = data.Text() - self.log.warning('unknown extension in data factory %s' % ext) + if ext is not None: + self.log.warning('unknown extension in data factory %s', ext) return builder def change_datatype(self, data, ext ): diff -r feb7438276fb -r 3f407d489ade lib/galaxy/model/mapping.py --- a/lib/galaxy/model/mapping.py Mon Jul 13 13:08:52 2009 -0400 +++ b/lib/galaxy/model/mapping.py Fri May 22 14:46:17 2009 -0400 @@ -690,7 +690,7 @@ assign_mapper( context, History, History.table, properties=dict( galaxy_sessions=relation( GalaxySessionToHistoryAssociation ), datasets=relation( HistoryDatasetAssociation, backref="history", order_by=asc(HistoryDatasetAssociation.table.c.hid) ), - active_datasets=relation( HistoryDatasetAssociation, primaryjoin=( ( HistoryDatasetAssociation.table.c.history_id == History.table.c.id ) & ( not_( HistoryDatasetAssociation.table.c.deleted ) ) ), order_by=asc( HistoryDatasetAssociation.table.c.hid ), lazy=False, viewonly=True ) + active_datasets=relation( HistoryDatasetAssociation, primaryjoin=( ( HistoryDatasetAssociation.table.c.history_id == History.table.c.id ) & ( not_( HistoryDatasetAssociation.table.c.deleted ) ) ), order_by=asc( HistoryDatasetAssociation.table.c.hid ), viewonly=True ) ) ) assign_mapper( context, HistoryUserShareAssociation, HistoryUserShareAssociation.table, diff -r feb7438276fb -r 3f407d489ade lib/galaxy/web/controllers/root.py --- a/lib/galaxy/web/controllers/root.py Mon Jul 13 13:08:52 2009 -0400 +++ b/lib/galaxy/web/controllers/root.py Fri May 22 14:46:17 2009 -0400 @@ -61,7 +61,18 @@ return trans.fill_template_mako( "root/history_as_xml.mako", history=history, show_deleted=util.string_as_bool( show_deleted ) ) else: template = "root/history.mako" - return trans.fill_template( "root/history.mako", history=history, show_deleted=util.string_as_bool( show_deleted ) ) + show_deleted = util.string_as_bool( show_deleted ) + query = trans.sa_session.query( model.HistoryDatasetAssociation ) \ + .filter( model.HistoryDatasetAssociation.history == history ) \ + .options( eagerload( "children" ) ) \ + .join( "dataset" ).filter( model.Dataset.purged == False ) \ + .options( eagerload_all( "dataset.actions" ) ) + if not show_deleted: + query.filter_by( deleted=False ) + return trans.stream_template_mako( "root/history.mako", + history = history, + datasets = query.all(), + show_deleted = show_deleted ) @web.expose def dataset_state ( self, trans, id=None, stamp=None ): diff -r feb7438276fb -r 3f407d489ade lib/galaxy/web/framework/__init__.py --- a/lib/galaxy/web/framework/__init__.py Mon Jul 13 13:08:52 2009 -0400 +++ b/lib/galaxy/web/framework/__init__.py Fri May 22 14:46:17 2009 -0400 @@ -23,6 +23,7 @@ pkg_resources.require( "Mako" ) import mako.template import mako.lookup +import mako.runtime pkg_resources.require( "Babel" ) from babel.support import Translations @@ -575,6 +576,23 @@ data.update( self.template_context ) data.update( kwargs ) return template.render( **data ) + def stream_template_mako( self, filename, **kwargs ): + template = self.webapp.mako_template_lookup.get_template( filename ) + template.output_encoding = 'utf-8' + data = dict( caller=self, t=self, trans=self, h=webhelpers, util=util, request=self.request, response=self.response, app=self.app ) + data.update( self.template_context ) + data.update( kwargs ) + ## return template.render( **data ) + def render( environ, start_response ): + response_write = start_response( self.response.wsgi_status(), + self.response.wsgi_headeritems() ) + class C: + def write( self, *args, **kwargs ): + response_write( *args, **kwargs ) + context = mako.runtime.Context( C(), **data ) + template.render_context( context ) + return [] + return render def fill_template_string(self, template_string, context=None, **kwargs): """ Fill in a template, putting any keyword arguments on the context. diff -r feb7438276fb -r 3f407d489ade templates/root/history.mako --- a/templates/root/history.mako Mon Jul 13 13:08:52 2009 -0400 +++ b/templates/root/history.mako Fri May 22 14:46:17 2009 -0400 @@ -70,7 +70,15 @@ $("#history-name-area").append( t ); t.focus(); return false; - }) + }); + // Updater + updater({ + %for data in reversed( datasets ): + %if data.visible and data.state not in [ "deleted", "empty", "error", "ok" ]: + "${data.id}": "${data.state}"; + %endif + %endfor + }); }) //' Functionized so AJAX'd datasets can call them // Get shown/hidden state from cookie @@ -80,7 +88,7 @@ var state = new CookieSet( "galaxy.history.expand_state" ); for ( id in state.store ) { if ( id ) { - $( "#" + id ).children( "div.historyItemBody" ).show(); + $( "#" + id + " div.historyItemBody" ).show(); } } // If Mozilla, hide scrollbars in hidden items since they cause animation bugs @@ -114,51 +122,51 @@ state.add( id ); state.save(); delete state; } - return false; + return false; }); // Delete link $(this).find( "a.historyItemDelete" ).each( function() { - var data_id = this.id.split( "-" )[1]; - $(this).click( function() { - $( '#progress-' + data_id ).show(); - $.ajax({ - url: "${h.url_for( action='delete_async', id='XXX' )}".replace( 'XXX', data_id ), - error: function() { alert( "Delete failed" ) }, - success: function() { - %if show_deleted: - var to_update = {}; - to_update[data_id] = "none"; - updater( to_update ); - %else: - $( "#historyItem-" + data_id ).fadeOut( "fast", function() { - $( "#historyItemContainer-" + data_id ).remove(); - if ( $( "div.historyItemContainer" ).length < 1 ) { - $( "#emptyHistoryMessage" ).show(); - } + var data_id = this.id.split( "-" )[1]; + $(this).click( function() { + $( '#progress-' + data_id ).show(); + $.ajax({ + url: "${h.url_for( action='delete_async', id='XXX' )}".replace( 'XXX', data_id ), + error: function() { alert( "Delete failed" ) }, + success: function() { + %if show_deleted: + var to_update = {}; + to_update[data_id] = "none"; + updater( to_update ); + %else: + $( "#historyItem-" + data_id ).fadeOut( "fast", function() { + $( "#historyItemContainer-" + data_id ).remove(); + if ( $( "div.historyItemContainer" ).length < 1 ) { + $( "#emptyHistoryMessage" ).show(); + } + }); + %endif + } + }); + return false; }); - %endif - } }); - return false; - }); - }); // Undelete link $(this).find( "a.historyItemUndelete" ).each( function() { - var data_id = this.id.split( "-" )[1]; - $(this).click( function() { - $( '#progress-' + data_id ).show(); - $.ajax({ - url: "${h.url_for( controller='dataset', action='undelete_async', id='XXX' )}".replace( 'XXX', data_id ), - error: function() { alert( "Undelete failed" ) }, - success: function() { - var to_update = {}; - to_update[data_id] = "none"; - updater( to_update ); - } + var data_id = this.id.split( "-" )[1]; + $(this).click( function() { + $( '#progress-' + data_id ).show(); + $.ajax({ + url: "${h.url_for( controller='dataset', action='undelete_async', id='XXX' )}".replace( 'XXX', data_id ), + error: function() { alert( "Undelete failed" ) }, + success: function() { + var to_update = {}; + to_update[data_id] = "none"; + updater( to_update ); + } + }); + return false; + }); }); - return false; - }); - }); }); }; // Looks for changes in dataset state using an async request. Keeps @@ -261,36 +269,21 @@ <%namespace file="history_common.mako" import="render_dataset" /> -<% activatable_datasets = history.activatable_datasets %> +%if not datasets: -%if ( show_deleted and not activatable_datasets ) or ( not show_deleted and not history.active_datasets ): <div class="infomessagesmall" id="emptyHistoryMessage"> + %else: - <% - if show_deleted: - ## All datasets - datasets_to_show = activatable_datasets - else: - ## Active (not deleted) - datasets_to_show = history.active_datasets - %> + ## Render requested datasets, ordered from newest to oldest - %for data in reversed( datasets_to_show ): + %for data in reversed( datasets ): %if data.visible: <div class="historyItemContainer" id="historyItemContainer-${data.id}"> ${render_dataset( data, data.hid, show_deleted_on_refresh = show_deleted )} </div> %endif %endfor - <script type="text/javascript"> - var tracked_datasets = {}; - %for data in reversed( history.active_datasets ): - %if data.visible and data.state not in [ "deleted", "empty", "error", "ok" ]: - tracked_datasets[ ${data.id} ] = "${data.state}"; - %endif - %endfor - updater( tracked_datasets ); - </script> + <div class="infomessagesmall" id="emptyHistoryMessage" style="display:none;"> %endif ${_("Your history is empty. Click 'Get Data' on the left pane to start")}