diff --git a/src/calibre/library/caches.py b/src/calibre/library/caches.py index 235584b9f7..8261ca40fb 100644 --- a/src/calibre/library/caches.py +++ b/src/calibre/library/caches.py @@ -28,6 +28,7 @@ class MetadataBackup(Thread): # {{{ self.daemon = True self.db = db self.dump_func = dump_func + self.dump_queue = Queue() self.keep_running = True def stop(self): @@ -42,13 +43,32 @@ class MetadataBackup(Thread): # {{{ except: # Happens during interpreter shutdown break - if self.dump_func([id_]) is None: + if self.dump_func([id_], dump_queue=self.dump_queue) is None: # An exception occurred in dump_func, retry once - prints('Failed to backup metadata for id:', id_, 'once') + prints('Failed to get backup metadata for id:', id_, 'once') time.sleep(2) - if not self.dump_func([id_]): - prints('Failed to backup metadata for id:', id_, 'again, giving up') - time.sleep(0.9) # Limit to one per second + if not self.dump_func([id_], dump_queue=self.dump_queue): + prints('Failed to get backup metadata for id:', id_, 'again, giving up') + while True: + try: + path, raw = self.dump_queue.get_nowait() + except: + break + else: + try: + with open(path, 'wb') as f: + f.write(raw) + except: + prints('Failed to write backup metadata for id:', id_, 'once') + time.sleep(2) + try: + with open(path, 'wb') as f: + f.write(raw) + except: + prints('Failed to write backup metadata for id:', id_, + 'again, giving up') + + time.sleep(0.2) # Limit to five per second # }}} diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index ee7c3206bf..61c52cf6b7 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -566,7 +566,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): def metadata_for_field(self, key): return self.field_metadata[key] - def dump_metadata(self, book_ids=None, remove_from_dirtied=True, commit=True): + def dump_metadata(self, book_ids=None, remove_from_dirtied=True, + commit=True, dump_queue=None): 'Write metadata for each record to an individual OPF file' if book_ids is None: book_ids = [x[0] for x in self.conn.get( @@ -580,9 +581,13 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): # cover is set/removed mi.cover = 'cover.jpg' raw = metadata_to_opf(mi) - path = self.abspath(book_id, index_is_id=True) - with open(os.path.join(path, 'metadata.opf'), 'wb') as f: - f.write(raw) + path = os.path.join(self.abspath(book_id, index_is_id=True), + 'metadata.opf') + if dump_queue is None: + with open(path, 'wb') as f: + f.write(raw) + else: + dump_queue.put((path, raw)) if remove_from_dirtied: self.conn.execute('DELETE FROM metadata_dirtied WHERE book=?', (book_id,))