Fix write_lock being help on db when postimport plugins are run

This commit is contained in:
Kovid Goyal 2013-08-05 00:00:34 +05:30
parent d03bfd7f3d
commit 27b36ebefc
2 changed files with 56 additions and 54 deletions

View File

@ -106,7 +106,8 @@ def add_catalog(cache, path, title):
from calibre.utils.date import utcnow from calibre.utils.date import utcnow
fmt = os.path.splitext(path)[1][1:].lower() fmt = os.path.splitext(path)[1][1:].lower()
with lopen(path, 'rb') as stream, cache.write_lock: with lopen(path, 'rb') as stream:
with cache.write_lock:
matches = cache._search('title:="%s" and tags:="%s"' % (title.replace('"', '\\"'), _('Catalog')), None) matches = cache._search('title:="%s" and tags:="%s"' % (title.replace('"', '\\"'), _('Catalog')), None)
db_id = None db_id = None
if matches: if matches:
@ -125,7 +126,7 @@ def add_catalog(cache, path, title):
db_id = cache._create_book_entry(mi, apply_import_tags=False) db_id = cache._create_book_entry(mi, apply_import_tags=False)
else: else:
cache._set_metadata(db_id, mi) cache._set_metadata(db_id, mi)
cache._add_format(db_id, fmt, stream) cache.add_format(db_id, fmt, stream) # Cant keep write lock since post-import hooks might run
return db_id return db_id
@ -156,7 +157,7 @@ def add_news(cache, path, arg):
mi.timestamp = utcnow() mi.timestamp = utcnow()
db_id = cache._create_book_entry(mi, apply_import_tags=False) db_id = cache._create_book_entry(mi, apply_import_tags=False)
cache._add_format(db_id, fmt, stream) cache.add_format(db_id, fmt, stream) # Cant keep write lock since post-import hooks might run
if not hasattr(path, 'read'): if not hasattr(path, 'read'):
stream.close() stream.close()

View File

@ -679,10 +679,9 @@ class Cache(object):
fmtfile = self.format(book_id, original_fmt, as_file=True) fmtfile = self.format(book_id, original_fmt, as_file=True)
if fmtfile is not None: if fmtfile is not None:
fmt = original_fmt.partition('_')[2] fmt = original_fmt.partition('_')[2]
with self.write_lock:
with fmtfile: with fmtfile:
self._add_format(book_id, fmt, fmtfile, run_hooks=False) self.add_format(book_id, fmt, fmtfile, run_hooks=False)
self._remove_formats({book_id:(original_fmt,)}) self.remove_formats({book_id:(original_fmt,)})
return True return True
return False return False
@ -1150,8 +1149,9 @@ class Cache(object):
self._reload_from_db() self._reload_from_db()
raise raise
@write_api @api
def add_format(self, book_id, fmt, stream_or_path, replace=True, run_hooks=True, dbapi=None): def add_format(self, book_id, fmt, stream_or_path, replace=True, run_hooks=True, dbapi=None):
with self.write_lock:
if run_hooks: if run_hooks:
# Run import plugins # Run import plugins
npath = run_import_plugins(stream_or_path, fmt) npath = run_import_plugins(stream_or_path, fmt)
@ -1181,7 +1181,8 @@ class Cache(object):
self._update_last_modified((book_id,)) self._update_last_modified((book_id,))
if run_hooks: if run_hooks:
# Run post import plugins # Run post import plugins, the write lock is released so the plugin
# can call api without a locking violation.
run_plugins_on_postimport(dbapi or self, book_id, fmt) run_plugins_on_postimport(dbapi or self, book_id, fmt)
stream_or_path.close() stream_or_path.close()
@ -1305,17 +1306,17 @@ class Cache(object):
return book_id return book_id
@write_api @api
def add_books(self, books, add_duplicates=True, apply_import_tags=True, preserve_uuid=False, run_hooks=True, dbapi=None): def add_books(self, books, add_duplicates=True, apply_import_tags=True, preserve_uuid=False, run_hooks=True, dbapi=None):
duplicates, ids = [], [] duplicates, ids = [], []
for mi, format_map in books: for mi, format_map in books:
book_id = self._create_book_entry(mi, add_duplicates=add_duplicates, apply_import_tags=apply_import_tags, preserve_uuid=preserve_uuid) book_id = self.create_book_entry(mi, add_duplicates=add_duplicates, apply_import_tags=apply_import_tags, preserve_uuid=preserve_uuid)
if book_id is None: if book_id is None:
duplicates.append((mi, format_map)) duplicates.append((mi, format_map))
else: else:
ids.append(book_id) ids.append(book_id)
for fmt, stream_or_path in format_map.iteritems(): for fmt, stream_or_path in format_map.iteritems():
self._add_format(book_id, fmt, stream_or_path, dbapi=dbapi, run_hooks=run_hooks) self.add_format(book_id, fmt, stream_or_path, dbapi=dbapi, run_hooks=run_hooks)
return ids, duplicates return ids, duplicates
@write_api @write_api