Repository: LMCache/LMCache
File: lmcache/integration/vllm/vllm_v1_adapter.py (Python)

Code before:
                    "GPU connector must be available for blending"
                )
                self.blender = LMCBlenderBuilder.get_or_create(
                    ENGINE_NAME,
                    self.lmcache_engine,
                    self.lmcache_engine.gpu_connector,
                    config,
                )

            # Create lookup server using factory
            assert self.lmcache_engine is not None
            self.lookup_server = LookupClientFactory.create_lookup_server(
                self.lmcache_engine, vllm_config
            )

            self.offload_server = ZMQOffloadServer(
                self.lmcache_engine,
                vllm_config,
                get_tensor_model_parallel_rank(),
            )

            # In case of MLA, the lookup server is only created on worker 0
            if self.async_loading and self.lookup_server is not None:
                # if the connector implements `register_kv_caches`, we do not need to
                # post init the lmcache engine here, do it in `register_kv_caches`.
                def implements_register_kv_caches():
                    child_class = self._parent.__class__
                    parent_class = KVConnectorBase_V1
                    child_method = getattr(child_class, "register_kv_caches", None)
                    parent_method = getattr(parent_class, "register_kv_caches", None)
                    if child_method is None or parent_method is None:
                        return False
                    return child_method is not parent_method

                if not implements_register_kv_caches():
                    logger.warning(
                        "Please use the latest lmcache connector, otherwise some "
                        "features may not work, such as DSA with async loading."
                    )
                    assert isinstance(self.lookup_server, LMCacheAsyncLookupServer)
                    self.lmcache_engine.post_init(
                        async_lookup_server=self.lookup_server
                    )

        self.kv_caches: dict[str, torch.Tensor] = {}

        self._block_size = vllm_config.cache_config.block_size

        # request_id -> (vllm cached tokens, lmcache cached tokens)
        self.load_specs: dict[str, LoadSpec] = {}


Review comment (bug):
if the `lmcache_connector` is not latest,  the `register_kv_caches` not implements, we must `post_init` the `lmcache_engine` to create `storage_manager`, otherwise the `lookup` will failed in `assert self.storage_manager is not None`

Code after:
                assert self.lmcache_engine.gpu_connector is not None, (
                    "GPU connector must be available for blending"
                )
                self.blender = LMCBlenderBuilder.get_or_create(
                    ENGINE_NAME,
                    self.lmcache_engine,
                    self.lmcache_engine.gpu_connector,
                    config,
                )

            # Create lookup server using factory
            assert self.lmcache_engine is not None
            self.lookup_server = LookupClientFactory.create_lookup_server(
                self.lmcache_engine, vllm_config
            )

            self.offload_server = ZMQOffloadServer(
                self.lmcache_engine,
                vllm_config,
                get_tensor_model_parallel_rank(),
            )

        # TODO(chunxiaozheng): use `register_kv_caches` replace, remove later
        # if the connector implements `register_kv_caches`, we do not need to
        # post init the lmcache engine here, do it in `register_kv_caches`.
        def implements_register_kv_caches():
            child_class = self._parent.__class__
            parent_class = KVConnectorBase_V1
            child_method = getattr(child_class, "register_kv_caches", None)
            parent_method = getattr(parent_class, "register_kv_caches", None)
            if child_method is None or parent_method is None:
                return False
            return child_method is not parent_method

        if self.lmcache_engine is not None and not implements_register_kv_caches():
            logger.warning(
                "Please use the latest lmcache connector, otherwise some "
                "features may not work, such as DSA"
            )
            # In case of MLA, the lookup server is only created on worker 0
            async_lookup_server = None
            if self.async_loading and self.lookup_server is not None:
                assert isinstance(self.lookup_server, LMCacheAsyncLookupServer)
                async_lookup_server = self.lookup_server
            self.lmcache_engine.post_init(async_lookup_server=async_lookup_server)

        self.kv_caches: dict[str, torch.Tensor] = {}

        self._block_size = vllm_config.cache_config.block_size

        # request_id -> (vllm cached tokens, lmcache cached tokens)