Delay load calibre C extensions. Worker launch is now under 0.07 seconds (only about 3 times the time taken to launch bare python)

This commit is contained in:
Kovid Goyal 2011-04-20 14:06:56 -06:00
parent 303a7c6b5c
commit 7fc7478c97
3 changed files with 48 additions and 24 deletions

View File

@ -12,7 +12,7 @@ __author__ = u"Kovid Goyal <kovid@kovidgoyal.net>"
Various run time constants.
'''
import sys, locale, codecs, os, importlib
import sys, locale, codecs, os, importlib, collections
_tc = None
def terminal_controller():
@ -52,15 +52,12 @@ def debug():
DEBUG = True
# plugins {{{
plugins = None
if plugins is None:
# Load plugins
def load_plugins():
plugins = {}
plugin_path = sys.extensions_location
sys.path.insert(0, plugin_path)
for plugin in [
class Plugins(collections.Mapping):
def __init__(self):
self._plugins = {}
plugins = [
'pictureflow',
'lzx',
'msdes',
@ -74,19 +71,44 @@ if plugins is None:
'chm_extra',
'icu',
'speedup',
] + \
(['winutil'] if iswindows else []) + \
(['usbobserver'] if isosx else []):
try:
p, err = importlib.import_module(plugin), ''
except Exception as err:
p = None
err = str(err)
plugins[plugin] = (p, err)
sys.path.remove(plugin_path)
return plugins
]
if iswindows:
plugins.append('winutil')
if isosx:
plugins.append(['usbobserver'])
self.plugins = frozenset(plugins)
plugins = load_plugins()
def load_plugin(self, name):
if name in self._plugins:
return
sys.path.insert(0, sys.extensions_location)
try:
p, err = importlib.import_module(name), ''
except Exception as err:
p = None
err = str(err)
self._plugins[name] = (p, err)
sys.path.remove(sys.extensions_location)
def __iter__(self):
return iter(self.plugins)
def __len__(self):
return len(self.plugins)
def __contains__(self, name):
return name in self.plugins
def __getitem__(self, name):
if name not in self.plugins:
raise KeyError('No plugin named %r'%name)
self.load_plugin(name)
return self._plugins[name]
plugins = None
if plugins is None:
plugins = Plugins()
# }}}
# config_dir {{{

View File

@ -8,7 +8,7 @@ manner.
import sys, os, re
from threading import RLock
from calibre import iswindows, isosx, plugins, islinux
from calibre.constants import iswindows, isosx, plugins, islinux
osx_scanner = win_scanner = linux_scanner = None

View File

@ -19,6 +19,9 @@ from calibre.utils.config import prefs, dynamic
from calibre.library.database2 import LibraryDatabase2
from calibre.library.sqlite import sqlite, DatabaseException
if iswindows:
winutil = plugins['winutil'][0]
def option_parser():
parser = _option_parser('''\
%prog [opts] [path_to_ebook]
@ -80,8 +83,7 @@ def get_library_path(parent=None):
if library_path is None: # Need to migrate to new database layout
base = os.path.expanduser('~')
if iswindows:
base = plugins['winutil'][0].special_folder_path(
plugins['winutil'][0].CSIDL_PERSONAL)
base = winutil.special_folder_path(winutil.CSIDL_PERSONAL)
if not base or not os.path.exists(base):
from PyQt4.Qt import QDir
base = unicode(QDir.homePath()).replace('/', os.sep)