Don't reuse source but instead copy from primary media store to backup
parent
b92a8e6e4a
commit
2b24416e90
|
@ -95,7 +95,7 @@ class MediaRepository(object):
|
||||||
os.makedirs(dirname)
|
os.makedirs(dirname)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _write_file_synchronously(source, fname, close_source=False):
|
def _write_file_synchronously(source, fname):
|
||||||
"""Write `source` to the path `fname` synchronously. Should be called
|
"""Write `source` to the path `fname` synchronously. Should be called
|
||||||
from a thread.
|
from a thread.
|
||||||
|
|
||||||
|
@ -109,16 +109,11 @@ class MediaRepository(object):
|
||||||
with open(fname, "wb") as f:
|
with open(fname, "wb") as f:
|
||||||
shutil.copyfileobj(source, f)
|
shutil.copyfileobj(source, f)
|
||||||
|
|
||||||
if close_source:
|
|
||||||
source.close()
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def write_to_file_and_backup(self, source, path):
|
def write_to_file_and_backup(self, source, path):
|
||||||
"""Write `source` to the on disk media store, and also the backup store
|
"""Write `source` to the on disk media store, and also the backup store
|
||||||
if configured.
|
if configured.
|
||||||
|
|
||||||
Will close source once finished.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
source: A file like object that should be written
|
source: A file like object that should be written
|
||||||
path (str): Relative path to write file to
|
path (str): Relative path to write file to
|
||||||
|
@ -134,37 +129,31 @@ class MediaRepository(object):
|
||||||
))
|
))
|
||||||
|
|
||||||
# Write to backup repository
|
# Write to backup repository
|
||||||
yield self.copy_to_backup(source, path)
|
yield self.copy_to_backup(path)
|
||||||
|
|
||||||
defer.returnValue(fname)
|
defer.returnValue(fname)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def copy_to_backup(self, source, path):
|
def copy_to_backup(self, path):
|
||||||
"""Copy file like object source to the backup media store, if configured.
|
"""Copy a file from the primary to backup media store, if configured.
|
||||||
|
|
||||||
Will close source after its done.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
source: A file like object that should be written
|
|
||||||
path(str): Relative path to write file to
|
path(str): Relative path to write file to
|
||||||
"""
|
"""
|
||||||
if self.backup_base_path:
|
if self.backup_base_path:
|
||||||
|
primary_fname = os.path.join(self.primary_base_path, path)
|
||||||
backup_fname = os.path.join(self.backup_base_path, path)
|
backup_fname = os.path.join(self.backup_base_path, path)
|
||||||
|
|
||||||
# We can either wait for successful writing to the backup repository
|
# We can either wait for successful writing to the backup repository
|
||||||
# or write in the background and immediately return
|
# or write in the background and immediately return
|
||||||
if self.synchronous_backup_media_store:
|
if self.synchronous_backup_media_store:
|
||||||
yield make_deferred_yieldable(threads.deferToThread(
|
yield make_deferred_yieldable(threads.deferToThread(
|
||||||
self._write_file_synchronously, source, backup_fname,
|
shutil.copyfile, primary_fname, backup_fname,
|
||||||
close_source=True,
|
|
||||||
))
|
))
|
||||||
else:
|
else:
|
||||||
preserve_fn(threads.deferToThread)(
|
preserve_fn(threads.deferToThread)(
|
||||||
self._write_file_synchronously, source, backup_fname,
|
shutil.copyfile, primary_fname, backup_fname,
|
||||||
close_source=True,
|
|
||||||
)
|
)
|
||||||
else:
|
|
||||||
source.close()
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def create_content(self, media_type, upload_name, content, content_length,
|
def create_content(self, media_type, upload_name, content, content_length,
|
||||||
|
@ -280,8 +269,7 @@ class MediaRepository(object):
|
||||||
server_name, media_id)
|
server_name, media_id)
|
||||||
raise SynapseError(502, "Failed to fetch remote media")
|
raise SynapseError(502, "Failed to fetch remote media")
|
||||||
|
|
||||||
# Will close the file after its done
|
yield self.copy_to_backup(fpath)
|
||||||
yield self.copy_to_backup(open(fname), fpath)
|
|
||||||
|
|
||||||
media_type = headers["Content-Type"][0]
|
media_type = headers["Content-Type"][0]
|
||||||
time_now_ms = self.clock.time_msec()
|
time_now_ms = self.clock.time_msec()
|
||||||
|
|
|
@ -275,8 +275,7 @@ class PreviewUrlResource(Resource):
|
||||||
)
|
)
|
||||||
# FIXME: pass through 404s and other error messages nicely
|
# FIXME: pass through 404s and other error messages nicely
|
||||||
|
|
||||||
# Will close the file after its done
|
yield self.media_repo.copy_to_backup(fpath)
|
||||||
yield self.media_repo.copy_to_backup(open(fname), fpath)
|
|
||||||
|
|
||||||
media_type = headers["Content-Type"][0]
|
media_type = headers["Content-Type"][0]
|
||||||
time_now_ms = self.clock.time_msec()
|
time_now_ms = self.clock.time_msec()
|
||||||
|
|
Loading…
Reference in New Issue