diff --git a/lib/galaxy/managers/context.py b/lib/galaxy/managers/context.py index d8fb528ee0b..6699b80432d 100644 --- a/lib/galaxy/managers/context.py +++ b/lib/galaxy/managers/context.py @@ -180,12 +180,24 @@ class ProvidesHistoryContext(object): # The API presents a Bunch for a history. Until the API is # more fully featured for handling this, also return None. return None - datasets = self.sa_session.query(self.app.model.HistoryDatasetAssociation) \ - .filter_by(deleted=False, history_id=self.history.id, extension="len") + non_ready_or_ok = set(self.app.model.Dataset.non_ready_states) + non_ready_or_ok.add(self.app.model.HistoryDatasetAssociation.states.OK) + datasets = self.sa_session.query( + self.app.model.HistoryDatasetAssociation + ).filter_by( + deleted=False, + history_id=self.history.id, + extension="len" + ).filter( + self.app.model.HistoryDatasetAssociation._state.in_(non_ready_or_ok), + ) + valid_ds = None for ds in datasets: - if dbkey == ds.dbkey: - return ds - return None + if ds.dbkey == dbkey: + if ds.state == self.app.model.HistoryDatasetAssociation.states.OK: + return ds + valid_ds = ds + return valid_ds @property def db_builds(self): diff --git a/lib/galaxy/tools/cache.py b/lib/galaxy/tools/cache.py index 768d1b1ab07..36ce418ab75 100644 --- a/lib/galaxy/tools/cache.py +++ b/lib/galaxy/tools/cache.py @@ -149,16 +149,20 @@ class ToolShedRepositoryCache(object): self.repos_by_tuple[(repository.tool_shed, repository.owner, repository.name)].append(repository) def rebuild(self): - self.repositories = self.app.install_model.context.current.query(self.app.install_model.ToolShedRepository).options( - defer(self.app.install_model.ToolShedRepository.metadata), - joinedload('tool_dependencies').subqueryload('tool_shed_repository').options( - defer(self.app.install_model.ToolShedRepository.metadata) - ), - ).all() - repos_by_tuple = defaultdict(list) - for repository in self.repositories + self.local_repositories: - repos_by_tuple[(repository.tool_shed, repository.owner, repository.name)].append(repository) - self.repos_by_tuple = repos_by_tuple + try: + session = self.app.install_model.context.current.session_factory() + self.repositories = session.query(self.app.install_model.ToolShedRepository).options( + defer(self.app.install_model.ToolShedRepository.metadata), + joinedload('tool_dependencies').subqueryload('tool_shed_repository').options( + defer(self.app.install_model.ToolShedRepository.metadata) + ), + ).all() + repos_by_tuple = defaultdict(list) + for repository in self.repositories + self.local_repositories: + repos_by_tuple[(repository.tool_shed, repository.owner, repository.name)].append(repository) + self.repos_by_tuple = repos_by_tuple + finally: + session.close() def get_installed_repository(self, tool_shed=None, name=None, owner=None, installed_changeset_revision=None, changeset_revision=None, repository_id=None): if repository_id: diff --git a/test/unit/tools/conftest.py b/test/unit/tools/conftest.py index a7de3f768bc..ab8d702131e 100644 --- a/test/unit/tools/conftest.py +++ b/test/unit/tools/conftest.py @@ -65,4 +65,13 @@ def create_repo(app, changeset, installed_changeset, config_filename=None): repository.deleted = False repository.uninstalled = False app.install_model.context.add(repository) + app.install_model.context.flush() + tool_dependency = tool_shed_install.ToolDependency( + name='Name', + version='100', + type='package', + status='ok', + tool_shed_repository_id=repository.id, + ) + app.install_model.context.add(tool_dependency) return repository diff --git a/test/unit/tools/test_tool_shed_repository_cache.py b/test/unit/tools/test_tool_shed_repository_cache.py index 383d8351191..ae99298292e 100644 --- a/test/unit/tools/test_tool_shed_repository_cache.py +++ b/test/unit/tools/test_tool_shed_repository_cache.py @@ -1,4 +1,5 @@ import pytest +from sqlalchemy.orm.exc import DetachedInstanceError from .conftest import create_repo @@ -54,3 +55,20 @@ def test_get_installed_repository(tool_shed_repository_cache, repos, tool_conf_r assert repo else: assert repo is None + + +def test_repo_cache_expunge(tool_shed_repository_cache, repos): + tool_shed_repository_cache.rebuild() + assert len(tool_shed_repository_cache.repositories) == 10 + # Modify and commit a repo, will expire in memory attributes of orm objects (unless using a different session) + repo = tool_shed_repository_cache.repositories[0] + repo.name = 'new name' + tool_shed_repository_cache.app.install_model.session.flush() + # remove session, should demonstrate the separate session is in use + tool_shed_repository_cache.app.install_model.session.remove() + assert repo.changeset_revision == "1" + assert repo.tool_dependencies[0].name == 'Name' + with pytest.raises(DetachedInstanceError): + # Make sure this still raises DetachedInstanceError, + # keeping this in memory would be expensive + repo.metadata