jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/400616 )
Change subject: Made download_dump.py download process atomic ...................................................................... Made download_dump.py download process atomic Bug: T183675 Change-Id: I142629bb89ffc1c810adcf8f1417ecc824594e41 --- M scripts/maintenance/download_dump.py 1 file changed, 66 insertions(+), 22 deletions(-) Approvals: Zhuyifei1999: Looks good to me, but someone else must approve Framawiki: Looks good to me, approved jenkins-bot: Verified diff --git a/scripts/maintenance/download_dump.py b/scripts/maintenance/download_dump.py index d3a5123..c55940b 100644 --- a/scripts/maintenance/download_dump.py +++ b/scripts/maintenance/download_dump.py @@ -18,10 +18,27 @@ # from __future__ import absolute_import, division, unicode_literals +import binascii + import os.path import sys -from os import remove, symlink +from os import remove, symlink, urandom + +try: + from os import replace +except ImportError: # py2 + if sys.platform == 'win32': + import os + + def replace(src, dst): + try: + os.rename(src, dst) + except OSError: + remove(dst) + os.rename(src, dst) + else: + from os import rename as replace import pywikibot @@ -63,36 +80,63 @@ download_filename = self.getOption('wikiname') + \ '-latest-' + self.getOption('filename') - file_storepath = os.path.join( + temp_filename = download_filename + '-' + \ + binascii.b2a_hex(urandom(8)).decode('ascii') + '.part' + + file_final_storepath = os.path.join( self.getOption('storepath'), download_filename) + file_current_storepath = os.path.join( + self.getOption('storepath'), temp_filename) # https://wikitech.wikimedia.org/wiki/Help:Toolforge#Dumps toolforge_dump_filepath = self.get_dump_name( self.getOption('wikiname'), self.getOption('filename')) - if toolforge_dump_filepath: - pywikibot.output('Symlinking file from ' + toolforge_dump_filepath) - if os.path.exists(file_storepath): - remove(file_storepath) - symlink(toolforge_dump_filepath, file_storepath) - else: - url = 'https://dumps.wikimedia.org/' + \ - os.path.join(self.getOption('wikiname'), - 'latest', download_filename) - pywikibot.output('Downloading file from ' + url) - response = fetch(url, stream=True) - if response.status == 200: + # First iteration for atomic download with temporary file + # Second iteration for fallback non-atomic download + for non_atomic in range(2): + try: + if toolforge_dump_filepath: + pywikibot.output('Symlinking file from ' + + toolforge_dump_filepath) + if non_atomic: + if os.path.exists(file_final_storepath): + remove(file_final_storepath) + symlink(toolforge_dump_filepath, file_current_storepath) + else: + url = 'https://dumps.wikimedia.org/{0}/latest/{1}'.format( + self.getOption('wikiname'), download_filename) + pywikibot.output('Downloading file from ' + url) + response = fetch(url, stream=True) + if response.status == 200: + with open(file_current_storepath, 'wb') as result_file: + for data in response.data.iter_content(100 * 1024): + result_file.write(data) + else: + return + # Rename the temporary file to the target file + # if the download completes successfully + if not non_atomic: + replace(file_current_storepath, file_final_storepath) + break + except (OSError, IOError): + pywikibot.exception() + try: - with open(file_storepath, 'wb') as result_file: - for chunk in response.data.iter_content(100 * 1024): - result_file.write(chunk) - except IOError: + remove(file_current_storepath) + except (OSError, IOError): pywikibot.exception() - return False - else: - return - pywikibot.output('Done! File stored as ' + file_storepath) + # If the atomic download fails, try without a temporary file + # If the non-atomic download also fails, exit the script + if not non_atomic: + pywikibot.output('Cannot make temporary file, ' + + 'falling back to non-atomic download') + file_current_storepath = file_final_storepath + else: + return False + + pywikibot.output('Done! File stored as ' + file_final_storepath) return -- To view, visit https://gerrit.wikimedia.org/r/400616 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I142629bb89ffc1c810adcf8f1417ecc824594e41 Gerrit-PatchSet: 12 Gerrit-Project: pywikibot/core Gerrit-Branch: master Gerrit-Owner: Ryan10145 <chang.ryan10...@gmail.com> Gerrit-Reviewer: Framawiki <framaw...@tools.wmflabs.org> Gerrit-Reviewer: John Vandenberg <jay...@gmail.com> Gerrit-Reviewer: Ryan10145 <chang.ryan10...@gmail.com> Gerrit-Reviewer: Zhuyifei1999 <zhuyifei1...@gmail.com> Gerrit-Reviewer: Zoranzoki21 <zorandori4...@gmail.com> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits