0 背景
openstack组件动态批量加载组件时会用到stevedore,stevedore可以批量加载插件,看了下源码总结了下使用方法和原理
1 原理
stevedore加载插件一般返回一个对象,对象初始化过程进行插件加载,目前用到的类有:ExtensionManager、DriverManager,namedExtensionManager
加载原理为实例初始化时传入参数,实例初始化会按照参数找到参数对应插件,具体实现是类方法list_entry_points(self),该方法将初始化入参对应的entrypoint加载。加载的主要功能由pkg_resources.iter_entry_points(self,namespace)实现
1.1 pkg_resources.iter_entry_points流程
该方法为实例方法,实例的类为pkg_resources.WorkingSet
1.1 初始化
初始化中加载了sys.path目录下所有以.egg-info, .dist-info结尾的模块,每个模块为一个实例,例如加载的/usr/lib/python/site-packages/kafka.egg-info对应的实例以字典形式储存在实例属性self.by_key中,可这样获取 self.by_key['/usr/lib/python/site-packages/kafka.egg-info']
1.2 iter_entry_points
该方法实际遍历实例WorkingSet的实例属性self.by_key,调用self.by_key中存储的对象的get_entry_map(group)方法获取传入endpoint对应的插件
2 思考
2.1 实际环境中,例如传入的endpoint为ceilometer.notification,返回的插件的定义在ceilometer-9.0.7.egg-info中,ceilometer与ceilometer-9.0.7.eeg-info的对应关系是怎样建立的?
对模块名解析,按-分割模块名,如ceilometer-9.0.7.egg-info对应的就是ceilometer
3 使用
ExtensionManager加载一个namespace下所有插件
DriverManager提供namespace和name,加载namespace下名为name的插件
namedextensionmanager,提供namespace和names,加载namespace下载names中的插件