下面这样的代码样例是一个典型的 nameko 例子
class AddService:
name = 'add_service'
dispatcher = EventDispatcher()
@event_handler('hi_api', 'rubbish')
def receive(self, message: str):
self.dispatcher('to_download', message)
你有好奇过 dispatcher = EventDispatcher()
是怎么拿到 amqp_uri、connection 这些信息的吗?
用你那个贫瘠的大脑好好思考一下,是不是很神奇,是不是惊为天人?
因为这里面没有任务的『继承』
所以是怎么实现的呢?看看标题就是知道了,必然是跟 nameko 的 Dependency 这个概念有关系。
多说懒得说,自己看源代码
为了帮你节约时间,我先贴几个关键源码
先来看看 EventDispatcher 的继承关系,理清脉络
从图中可知,EventDispatcher 是 DependencyProvider 的子子类,一切的关键就是这个 DependencyProvider
让我们来看看 DependencyProvider 的源码
site-packages/nameko/containers.py
class ServiceContainer(object):
def __init__(self, service_cls, config):
self.service_cls = service_cls
self.config = config
self.service_name = get_service_name(service_cls)
self.shared_extensions = {}
self.max_workers = (
config.get(MAX_WORKERS_CONFIG_KEY) or DEFAULT_MAX_WORKERS)
self.serializer, self.accept = serialization.setup(self.config)
self.entrypoints = SpawningSet()
self.dependencies = SpawningSet()
self.subextensions = SpawningSet()
for attr_name, dependency in inspect.getmembers(service_cls,
is_dependency):
bound = dependency.bind(self.interface, attr_name)
self.dependencies.add(bound)
self.subextensions.update(iter_extensions(bound))
for method_name, method in inspect.getmembers(service_cls, is_method):
entrypoints = getattr(method, ENTRYPOINT_EXTENSIONS_ATTR, [])
for entrypoint in entrypoints:
bound = entrypoint.bind(self.interface, method_name)
self.entrypoints.add(bound)
self.subextensions.update(iter_extensions(bound))
self.started = False
self._worker_pool = GreenPool(size=self.max_workers)
self._worker_threads = {}
self._managed_threads = {}
self._being_killed = False
self._died = Event()
关键是这部分
for attr_name, dependency in inspect.getmembers(service_cls,
is_dependency):
bound = dependency.bind(self.interface, attr_name)
self.dependencies.add(bound)
self.subextensions.update(iter_extensions(bound))