nameko 的内联绑定和 Dependency 解读

下面这样的代码样例是一个典型的 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))

你可能感兴趣的:(python)