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
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)
db_id = None
if matches:
@ -125,7 +126,7 @@ def add_catalog(cache, path, title):
db_id = cache._create_book_entry(mi, apply_import_tags=False)
else:
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
@ -156,7 +157,7 @@ def add_news(cache, path, arg):
mi.timestamp = utcnow()
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'):
stream.close()

View File

@ -679,10 +679,9 @@ class Cache(object):
fmtfile = self.format(book_id, original_fmt, as_file=True)
if fmtfile is not None:
fmt = original_fmt.partition('_')[2]
with self.write_lock:
with fmtfile:
self._add_format(book_id, fmt, fmtfile, run_hooks=False)
self._remove_formats({book_id:(original_fmt,)})
self.add_format(book_id, fmt, fmtfile, run_hooks=False)
self.remove_formats({book_id:(original_fmt,)})
return True
return False
@ -1150,8 +1149,9 @@ class Cache(object):
self._reload_from_db()
raise
@write_api
@api
def add_format(self, book_id, fmt, stream_or_path, replace=True, run_hooks=True, dbapi=None):
with self.write_lock:
if run_hooks:
# Run import plugins
npath = run_import_plugins(stream_or_path, fmt)
@ -1181,7 +1181,8 @@ class Cache(object):
self._update_last_modified((book_id,))
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)
stream_or_path.close()
@ -1305,17 +1306,17 @@ class Cache(object):
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):
duplicates, ids = [], []
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:
duplicates.append((mi, format_map))
else:
ids.append(book_id)
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
@write_api