From 1a43ef5b83d7378faa653451ebc38a54725a7481 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Thu, 18 Jan 2018 17:48:32 +0100 Subject: [PATCH 1/3] Work around (temporarily) wrong getsize() output I'm not sure how/why this happens, but this can be reproduced by copying a file to a location in one process, while checking the size in another process: Run this to copy a file indefinitely: ``` import os import shutil open('test').write("foo") while True: shutil.copy('test', 'test.file') os.remove('test.file') ``` In the same directory run this ``` import os count = 0 wrong_size = False while True: try: size = os.path.getsize('test.file') if size == 0: wrong_size = True wrong_count = count elif wrong_size and os.path.getsize('test.file') != 0: # We have seen the wrong size being reported, but now it's correct again print("Got wrong file size at %dnd try, was fixed in %dnd try" % (wrong_count, count)) break except Exception: pass count += 1 ``` It'll (probably) fail like this: ``` Got wrong file size at 0nd try, was fixed in 1nd try ``` or more often: ``` Got wrong file size at 31nd try, was fixed in 32nd try ``` This seems to be fixed when running os.path.getsize() another time, so we simply do that here. --- lib/galaxy/objectstore/__init__.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/galaxy/objectstore/__init__.py b/lib/galaxy/objectstore/__init__.py index dc0c25668b6..bb9504f08f0 100644 --- a/lib/galaxy/objectstore/__init__.py +++ b/lib/galaxy/objectstore/__init__.py @@ -10,6 +10,7 @@ import os import random import shutil import threading +import time from xml.etree import ElementTree try: @@ -367,7 +368,12 @@ class DiskObjectStore(ObjectStore): """ if self.exists(obj, **kwargs): try: - return os.path.getsize(self.get_filename(obj, **kwargs)) + size = os.path.getsize(self.get_filename(obj, **kwargs)) + if size == 0: + # May be legitimately 0, or there may be an issue with the FS / kernel, so we try again + time.sleep(0.01) + size = os.path.getsize(self.get_filename(obj, **kwargs)) + return size except OSError: return 0 else: From 16344a62d3a8f30f4c468b552ce49ca989a1f0b7 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Thu, 18 Jan 2018 15:03:16 +0100 Subject: [PATCH 2/3] Alternative fix for missing metadata on datasets that report output size 0 --- lib/galaxy/jobs/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/jobs/__init__.py b/lib/galaxy/jobs/__init__.py index de1c32538bc..1bb036495de 100644 --- a/lib/galaxy/jobs/__init__.py +++ b/lib/galaxy/jobs/__init__.py @@ -1251,7 +1251,7 @@ class JobWrapper(object, HasResourceParameters): if job.states.ERROR == final_job_state: dataset.blurb = "error" dataset.mark_unhidden() - elif not purged and dataset.has_data(): + elif not purged: # If the tool was expected to set the extension, attempt to retrieve it if dataset.ext == 'auto': dataset.extension = context.get('ext', 'data') @@ -1299,7 +1299,7 @@ class JobWrapper(object, HasResourceParameters): except Exception: dataset.set_peek() else: - # Handle an empty dataset. + # Handle purged datasets. dataset.blurb = "empty" if dataset.ext == 'auto': dataset.extension = context.get('ext', 'txt') From 161467513b3f911cde15b890c404ed373f4571f4 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Thu, 18 Jan 2018 20:22:07 +0100 Subject: [PATCH 3/3] Use a for loop when checking size in object store and adjust `empty()` to use the new code. Thanks @nsoranzo. --- lib/galaxy/objectstore/__init__.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/galaxy/objectstore/__init__.py b/lib/galaxy/objectstore/__init__.py index bb9504f08f0..8144f8167df 100644 --- a/lib/galaxy/objectstore/__init__.py +++ b/lib/galaxy/objectstore/__init__.py @@ -359,7 +359,7 @@ class DiskObjectStore(ObjectStore): def empty(self, obj, **kwargs): """Override `ObjectStore`'s stub by checking file size on disk.""" - return os.path.getsize(self.get_filename(obj, **kwargs)) == 0 + return self.size(obj, **kwargs) == 0 def size(self, obj, **kwargs): """Override `ObjectStore`'s stub by return file size on disk. @@ -368,11 +368,13 @@ class DiskObjectStore(ObjectStore): """ if self.exists(obj, **kwargs): try: - size = os.path.getsize(self.get_filename(obj, **kwargs)) - if size == 0: + filepath = self.get_filename(obj, **kwargs) + for _ in range(0, 2): + size = os.path.getsize(filepath) + if size != 0: + break # May be legitimately 0, or there may be an issue with the FS / kernel, so we try again time.sleep(0.01) - size = os.path.getsize(self.get_filename(obj, **kwargs)) return size except OSError: return 0