lmcache-cli 0.4.5.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lmcache/__init__.py +84 -0
- lmcache/_version.py +24 -0
- lmcache/cli/__init__.py +1 -0
- lmcache/cli/commands/__init__.py +34 -0
- lmcache/cli/commands/base.py +157 -0
- lmcache/cli/commands/bench/__init__.py +557 -0
- lmcache/cli/commands/bench/engine_bench/__init__.py +1 -0
- lmcache/cli/commands/bench/engine_bench/config.py +245 -0
- lmcache/cli/commands/bench/engine_bench/interactive/__init__.py +274 -0
- lmcache/cli/commands/bench/engine_bench/interactive/config.json +10 -0
- lmcache/cli/commands/bench/engine_bench/interactive/schema.py +352 -0
- lmcache/cli/commands/bench/engine_bench/interactive/state.py +327 -0
- lmcache/cli/commands/bench/engine_bench/interactive/terminal.py +291 -0
- lmcache/cli/commands/bench/engine_bench/progress.py +145 -0
- lmcache/cli/commands/bench/engine_bench/request_sender.py +232 -0
- lmcache/cli/commands/bench/engine_bench/stats.py +275 -0
- lmcache/cli/commands/bench/engine_bench/workloads/__init__.py +153 -0
- lmcache/cli/commands/bench/engine_bench/workloads/base.py +122 -0
- lmcache/cli/commands/bench/engine_bench/workloads/long_doc_permutator.py +435 -0
- lmcache/cli/commands/bench/engine_bench/workloads/long_doc_qa.py +281 -0
- lmcache/cli/commands/bench/engine_bench/workloads/multi_round_chat.py +337 -0
- lmcache/cli/commands/bench/engine_bench/workloads/random_prefill.py +178 -0
- lmcache/cli/commands/describe.py +310 -0
- lmcache/cli/commands/kvcache.py +133 -0
- lmcache/cli/commands/mock.py +75 -0
- lmcache/cli/commands/ping.py +113 -0
- lmcache/cli/commands/query/__init__.py +155 -0
- lmcache/cli/commands/query/prompt.py +134 -0
- lmcache/cli/commands/query/request.py +357 -0
- lmcache/cli/commands/server.py +99 -0
- lmcache/cli/commands/tool/__init__.py +63 -0
- lmcache/cli/commands/tool/cache_simulator.py +113 -0
- lmcache/cli/commands/trace/__init__.py +505 -0
- lmcache/cli/commands/trace/dispatch.py +249 -0
- lmcache/cli/commands/trace/driver.py +372 -0
- lmcache/cli/commands/trace/stats.py +289 -0
- lmcache/cli/documents/lmcache.txt +11 -0
- lmcache/cli/main.py +42 -0
- lmcache/cli/metrics/__init__.py +29 -0
- lmcache/cli/metrics/formatter.py +171 -0
- lmcache/cli/metrics/handler.py +94 -0
- lmcache/cli/metrics/metrics.py +161 -0
- lmcache/cli/metrics/section.py +77 -0
- lmcache/connections.py +173 -0
- lmcache/integration/__init__.py +2 -0
- lmcache/integration/base_service_factory.py +165 -0
- lmcache/integration/request_telemetry/__init__.py +1 -0
- lmcache/integration/request_telemetry/base.py +51 -0
- lmcache/integration/request_telemetry/factory.py +113 -0
- lmcache/integration/request_telemetry/fastapi.py +109 -0
- lmcache/integration/request_telemetry/noop.py +35 -0
- lmcache/integration/sglang/__init__.py +2 -0
- lmcache/integration/sglang/sglang_adapter.py +326 -0
- lmcache/integration/sglang/utils.py +39 -0
- lmcache/integration/vllm/__init__.py +1 -0
- lmcache/integration/vllm/lmcache_connector_v1.py +213 -0
- lmcache/integration/vllm/lmcache_connector_v1_085.py +150 -0
- lmcache/integration/vllm/lmcache_mp_connector_0180.py +1072 -0
- lmcache/integration/vllm/tests/test_mm_hash_utils.py +112 -0
- lmcache/integration/vllm/utils.py +433 -0
- lmcache/integration/vllm/vllm_multi_process_adapter.py +1090 -0
- lmcache/integration/vllm/vllm_service_factory.py +339 -0
- lmcache/integration/vllm/vllm_v1_adapter.py +1713 -0
- lmcache/logging.py +107 -0
- lmcache/native_storage_ops.pyi +230 -0
- lmcache/non_cuda_equivalents.py +1424 -0
- lmcache/observability.py +1958 -0
- lmcache/storage_backend/serde/__init__.py +1 -0
- lmcache/storage_backend/serde/cachegen_basics.py +210 -0
- lmcache/storage_backend/serde/cachegen_decoder.py +207 -0
- lmcache/storage_backend/serde/cachegen_encoder.py +394 -0
- lmcache/storage_backend/serde/serde.py +75 -0
- lmcache/tools/__init__.py +1 -0
- lmcache/tools/cache_simulator/README.md +392 -0
- lmcache/tools/cache_simulator/__init__.py +1 -0
- lmcache/tools/cache_simulator/docs/simulate_example.png +0 -0
- lmcache/tools/cache_simulator/docs/sweep_example.png +0 -0
- lmcache/tools/cache_simulator/gen_bench_dataset.py +360 -0
- lmcache/tools/cache_simulator/lru_cache.py +124 -0
- lmcache/tools/cache_simulator/plot_hit_rate.py +231 -0
- lmcache/tools/cache_simulator/simulator.py +795 -0
- lmcache/tools/controller_benchmark/README.md +161 -0
- lmcache/tools/controller_benchmark/__init__.py +1 -0
- lmcache/tools/controller_benchmark/__main__.py +331 -0
- lmcache/tools/controller_benchmark/benchmark.py +660 -0
- lmcache/tools/controller_benchmark/config.py +44 -0
- lmcache/tools/controller_benchmark/constants.py +10 -0
- lmcache/tools/controller_benchmark/handlers/__init__.py +46 -0
- lmcache/tools/controller_benchmark/handlers/admit.py +52 -0
- lmcache/tools/controller_benchmark/handlers/base.py +47 -0
- lmcache/tools/controller_benchmark/handlers/deregister.py +49 -0
- lmcache/tools/controller_benchmark/handlers/evict.py +52 -0
- lmcache/tools/controller_benchmark/handlers/heartbeat.py +56 -0
- lmcache/tools/controller_benchmark/handlers/p2p_lookup.py +47 -0
- lmcache/tools/controller_benchmark/handlers/register.py +56 -0
- lmcache/tools/mp_status_viewer/__init__.py +1 -0
- lmcache/tools/mp_status_viewer/__main__.py +95 -0
- lmcache/usage_context.py +417 -0
- lmcache/utils.py +665 -0
- lmcache/v1/__init__.py +2 -0
- lmcache/v1/api_server/__init__.py +2 -0
- lmcache/v1/api_server/__main__.py +537 -0
- lmcache/v1/basic_check.py +112 -0
- lmcache/v1/cache_controller/__init__.py +9 -0
- lmcache/v1/cache_controller/commands/__init__.py +15 -0
- lmcache/v1/cache_controller/commands/base.py +35 -0
- lmcache/v1/cache_controller/commands/full_sync.py +49 -0
- lmcache/v1/cache_controller/config.py +176 -0
- lmcache/v1/cache_controller/controller_manager.py +535 -0
- lmcache/v1/cache_controller/controllers/__init__.py +11 -0
- lmcache/v1/cache_controller/controllers/full_sync_tracker.py +473 -0
- lmcache/v1/cache_controller/controllers/kv_controller.py +439 -0
- lmcache/v1/cache_controller/controllers/registration_controller.py +282 -0
- lmcache/v1/cache_controller/executor.py +463 -0
- lmcache/v1/cache_controller/frontend/static/css/style.css +201 -0
- lmcache/v1/cache_controller/frontend/static/img/logo.png +0 -0
- lmcache/v1/cache_controller/frontend/static/index.html +234 -0
- lmcache/v1/cache_controller/frontend/static/js/controller_app.js +660 -0
- lmcache/v1/cache_controller/full_sync_sender.py +475 -0
- lmcache/v1/cache_controller/locks.py +149 -0
- lmcache/v1/cache_controller/message.py +828 -0
- lmcache/v1/cache_controller/observability.py +208 -0
- lmcache/v1/cache_controller/utils.py +679 -0
- lmcache/v1/cache_controller/worker.py +665 -0
- lmcache/v1/cache_engine.py +2058 -0
- lmcache/v1/cache_interface.py +19 -0
- lmcache/v1/check/__init__.py +74 -0
- lmcache/v1/check/check_mode_gen.py +86 -0
- lmcache/v1/check/check_mode_test_l2_adapter.py +284 -0
- lmcache/v1/check/check_mode_test_remote.py +155 -0
- lmcache/v1/check/check_mode_test_storage_manager.py +142 -0
- lmcache/v1/check/utils.py +571 -0
- lmcache/v1/compute/__init__.py +2 -0
- lmcache/v1/compute/attention/__init__.py +0 -0
- lmcache/v1/compute/attention/abstract.py +39 -0
- lmcache/v1/compute/attention/flash_attn.py +129 -0
- lmcache/v1/compute/attention/flash_infer_sparse.py +284 -0
- lmcache/v1/compute/attention/metadata.py +85 -0
- lmcache/v1/compute/attention/utils.py +14 -0
- lmcache/v1/compute/blend/__init__.py +7 -0
- lmcache/v1/compute/blend/blender.py +168 -0
- lmcache/v1/compute/blend/metadata.py +34 -0
- lmcache/v1/compute/blend/utils.py +63 -0
- lmcache/v1/compute/models/__init__.py +0 -0
- lmcache/v1/compute/models/base.py +141 -0
- lmcache/v1/compute/models/llama.py +9 -0
- lmcache/v1/compute/models/qwen3.py +24 -0
- lmcache/v1/compute/models/utils.py +68 -0
- lmcache/v1/compute/positional_encoding.py +199 -0
- lmcache/v1/config.py +848 -0
- lmcache/v1/config_base.py +848 -0
- lmcache/v1/distributed/api.py +248 -0
- lmcache/v1/distributed/config.py +321 -0
- lmcache/v1/distributed/error.py +64 -0
- lmcache/v1/distributed/eviction.py +192 -0
- lmcache/v1/distributed/eviction_policy/__init__.py +21 -0
- lmcache/v1/distributed/eviction_policy/factory.py +27 -0
- lmcache/v1/distributed/eviction_policy/lru.py +244 -0
- lmcache/v1/distributed/eviction_policy/noop.py +50 -0
- lmcache/v1/distributed/internal_api.py +170 -0
- lmcache/v1/distributed/l1_manager.py +835 -0
- lmcache/v1/distributed/l2_adapters/__init__.py +67 -0
- lmcache/v1/distributed/l2_adapters/base.py +360 -0
- lmcache/v1/distributed/l2_adapters/config.py +385 -0
- lmcache/v1/distributed/l2_adapters/factory.py +205 -0
- lmcache/v1/distributed/l2_adapters/fs_l2_adapter.py +747 -0
- lmcache/v1/distributed/l2_adapters/fs_native_l2_adapter.py +167 -0
- lmcache/v1/distributed/l2_adapters/mock_l2_adapter.py +516 -0
- lmcache/v1/distributed/l2_adapters/mooncake_store_l2_adapter.py +135 -0
- lmcache/v1/distributed/l2_adapters/native_connector_l2_adapter.py +468 -0
- lmcache/v1/distributed/l2_adapters/native_plugin_l2_adapter.py +199 -0
- lmcache/v1/distributed/l2_adapters/nixl_store_dynamic_l2_adapter.py +831 -0
- lmcache/v1/distributed/l2_adapters/nixl_store_l2_adapter.py +983 -0
- lmcache/v1/distributed/l2_adapters/plugin_l2_adapter.py +210 -0
- lmcache/v1/distributed/l2_adapters/resp_l2_adapter.py +176 -0
- lmcache/v1/distributed/memory_manager.py +179 -0
- lmcache/v1/distributed/storage_controller.py +39 -0
- lmcache/v1/distributed/storage_controllers/__init__.py +43 -0
- lmcache/v1/distributed/storage_controllers/eviction_controller.py +242 -0
- lmcache/v1/distributed/storage_controllers/prefetch_controller.py +830 -0
- lmcache/v1/distributed/storage_controllers/prefetch_policy.py +193 -0
- lmcache/v1/distributed/storage_controllers/store_controller.py +452 -0
- lmcache/v1/distributed/storage_controllers/store_policy.py +213 -0
- lmcache/v1/distributed/storage_manager.py +532 -0
- lmcache/v1/event_manager.py +145 -0
- lmcache/v1/exceptions/__init__.py +16 -0
- lmcache/v1/gpu_connector/__init__.py +126 -0
- lmcache/v1/gpu_connector/gpu_connectors.py +1906 -0
- lmcache/v1/gpu_connector/gpu_ops.py +85 -0
- lmcache/v1/gpu_connector/hpu_connector.py +326 -0
- lmcache/v1/gpu_connector/mock_gpu_connector.py +67 -0
- lmcache/v1/gpu_connector/utils.py +890 -0
- lmcache/v1/gpu_connector/xpu_connectors.py +916 -0
- lmcache/v1/health_monitor/__init__.py +1 -0
- lmcache/v1/health_monitor/base.py +587 -0
- lmcache/v1/health_monitor/checks/__init__.py +1 -0
- lmcache/v1/health_monitor/checks/remote_backend_check.py +304 -0
- lmcache/v1/health_monitor/constants.py +36 -0
- lmcache/v1/internal_api_server/__init__.py +0 -0
- lmcache/v1/internal_api_server/api_registry.py +59 -0
- lmcache/v1/internal_api_server/api_server.py +120 -0
- lmcache/v1/internal_api_server/common/__init__.py +1 -0
- lmcache/v1/internal_api_server/common/env_api.py +22 -0
- lmcache/v1/internal_api_server/common/loglevel_api.py +57 -0
- lmcache/v1/internal_api_server/common/metrics_api.py +29 -0
- lmcache/v1/internal_api_server/common/periodic_thread_api.py +138 -0
- lmcache/v1/internal_api_server/common/run_script_api.py +73 -0
- lmcache/v1/internal_api_server/common/thread_api.py +63 -0
- lmcache/v1/internal_api_server/controller/__init__.py +1 -0
- lmcache/v1/internal_api_server/controller/key_stats_api.py +81 -0
- lmcache/v1/internal_api_server/controller/worker_info_api.py +136 -0
- lmcache/v1/internal_api_server/utils.py +43 -0
- lmcache/v1/internal_api_server/vllm/__init__.py +1 -0
- lmcache/v1/internal_api_server/vllm/backend_api.py +221 -0
- lmcache/v1/internal_api_server/vllm/bypass_api.py +204 -0
- lmcache/v1/internal_api_server/vllm/cache_api.py +895 -0
- lmcache/v1/internal_api_server/vllm/chunk_statistics_api.py +141 -0
- lmcache/v1/internal_api_server/vllm/conf_api.py +147 -0
- lmcache/v1/internal_api_server/vllm/freeze_api.py +172 -0
- lmcache/v1/internal_api_server/vllm/hot_cache_api.py +184 -0
- lmcache/v1/internal_api_server/vllm/inference_api.py +65 -0
- lmcache/v1/internal_api_server/vllm/load_fs_chunks_api.py +320 -0
- lmcache/v1/internal_api_server/vllm/lookup_api.py +145 -0
- lmcache/v1/internal_api_server/vllm/version_api.py +25 -0
- lmcache/v1/kv_layer_groups.py +267 -0
- lmcache/v1/lazy_memory_allocator.py +284 -0
- lmcache/v1/lookup_client/__init__.py +25 -0
- lmcache/v1/lookup_client/abstract_client.py +77 -0
- lmcache/v1/lookup_client/async_lookup_message.py +50 -0
- lmcache/v1/lookup_client/chunk_statistics_lookup_client.py +200 -0
- lmcache/v1/lookup_client/factory.py +251 -0
- lmcache/v1/lookup_client/hit_limit_lookup_client.py +86 -0
- lmcache/v1/lookup_client/lmcache_async_lookup_client.py +407 -0
- lmcache/v1/lookup_client/lmcache_lookup_client.py +285 -0
- lmcache/v1/lookup_client/lmcache_lookup_client_bypass.py +99 -0
- lmcache/v1/lookup_client/mooncake_lookup_client.py +87 -0
- lmcache/v1/lookup_client/record_strategies/__init__.py +77 -0
- lmcache/v1/lookup_client/record_strategies/base.py +327 -0
- lmcache/v1/lookup_client/record_strategies/file_hash.py +130 -0
- lmcache/v1/lookup_client/record_strategies/memory_bloom_filter.py +81 -0
- lmcache/v1/manager.py +539 -0
- lmcache/v1/memory_management.py +2619 -0
- lmcache/v1/metadata.py +114 -0
- lmcache/v1/mp_observability/AGENTS.override.md +21 -0
- lmcache/v1/mp_observability/README.md +204 -0
- lmcache/v1/mp_observability/config.py +340 -0
- lmcache/v1/mp_observability/event.py +100 -0
- lmcache/v1/mp_observability/event_bus.py +313 -0
- lmcache/v1/mp_observability/otel_init.py +145 -0
- lmcache/v1/mp_observability/subscribers/__init__.py +28 -0
- lmcache/v1/mp_observability/subscribers/logging/__init__.py +19 -0
- lmcache/v1/mp_observability/subscribers/logging/l1.py +56 -0
- lmcache/v1/mp_observability/subscribers/logging/l2.py +73 -0
- lmcache/v1/mp_observability/subscribers/logging/lookup_hash.py +209 -0
- lmcache/v1/mp_observability/subscribers/logging/mp_server.py +90 -0
- lmcache/v1/mp_observability/subscribers/logging/sm.py +59 -0
- lmcache/v1/mp_observability/subscribers/metrics/__init__.py +20 -0
- lmcache/v1/mp_observability/subscribers/metrics/l0_lifecycle.py +290 -0
- lmcache/v1/mp_observability/subscribers/metrics/l1.py +55 -0
- lmcache/v1/mp_observability/subscribers/metrics/l1_lifecycle.py +166 -0
- lmcache/v1/mp_observability/subscribers/metrics/l2.py +121 -0
- lmcache/v1/mp_observability/subscribers/metrics/sm.py +69 -0
- lmcache/v1/mp_observability/subscribers/tracing/__init__.py +12 -0
- lmcache/v1/mp_observability/subscribers/tracing/mp_server.py +333 -0
- lmcache/v1/mp_observability/subscribers/tracing/span_registry.py +148 -0
- lmcache/v1/mp_observability/trace/__init__.py +50 -0
- lmcache/v1/mp_observability/trace/codecs.py +255 -0
- lmcache/v1/mp_observability/trace/decorator.py +147 -0
- lmcache/v1/mp_observability/trace/format.py +132 -0
- lmcache/v1/mp_observability/trace/lifecycle.py +83 -0
- lmcache/v1/mp_observability/trace/reader.py +167 -0
- lmcache/v1/mp_observability/trace/recorder.py +300 -0
- lmcache/v1/multiprocess/__init__.py +0 -0
- lmcache/v1/multiprocess/affinity_pool.py +102 -0
- lmcache/v1/multiprocess/blend_server_v2.py +891 -0
- lmcache/v1/multiprocess/config.py +253 -0
- lmcache/v1/multiprocess/custom_types.py +281 -0
- lmcache/v1/multiprocess/futures.py +194 -0
- lmcache/v1/multiprocess/gpu_context.py +511 -0
- lmcache/v1/multiprocess/http_server.py +235 -0
- lmcache/v1/multiprocess/mp_runtime_plugin_launcher.py +130 -0
- lmcache/v1/multiprocess/mq.py +732 -0
- lmcache/v1/multiprocess/protocol.py +86 -0
- lmcache/v1/multiprocess/protocols/README.md +213 -0
- lmcache/v1/multiprocess/protocols/__init__.py +127 -0
- lmcache/v1/multiprocess/protocols/base.py +89 -0
- lmcache/v1/multiprocess/protocols/blend.py +109 -0
- lmcache/v1/multiprocess/protocols/blend_v2.py +57 -0
- lmcache/v1/multiprocess/protocols/controller.py +53 -0
- lmcache/v1/multiprocess/protocols/debug.py +34 -0
- lmcache/v1/multiprocess/protocols/engine.py +146 -0
- lmcache/v1/multiprocess/protocols/observability.py +39 -0
- lmcache/v1/multiprocess/server.py +1134 -0
- lmcache/v1/multiprocess/session.py +190 -0
- lmcache/v1/multiprocess/token_hasher.py +441 -0
- lmcache/v1/offload_server/__init__.py +17 -0
- lmcache/v1/offload_server/abstract_server.py +37 -0
- lmcache/v1/offload_server/message.py +30 -0
- lmcache/v1/offload_server/zmq_server.py +122 -0
- lmcache/v1/periodic_thread.py +579 -0
- lmcache/v1/pin_monitor.py +246 -0
- lmcache/v1/plugin/__init__.py +0 -0
- lmcache/v1/plugin/runtime_plugin_launcher.py +211 -0
- lmcache/v1/protocol.py +317 -0
- lmcache/v1/rpc/__init__.py +17 -0
- lmcache/v1/rpc/transport.py +105 -0
- lmcache/v1/rpc/zmq_transport.py +213 -0
- lmcache/v1/rpc_utils.py +165 -0
- lmcache/v1/server/__init__.py +2 -0
- lmcache/v1/server/__main__.py +170 -0
- lmcache/v1/server/storage_backend/__init__.py +21 -0
- lmcache/v1/server/storage_backend/abstract_backend.py +80 -0
- lmcache/v1/server/storage_backend/local_backend.py +75 -0
- lmcache/v1/server/utils.py +21 -0
- lmcache/v1/standalone/__init__.py +1 -0
- lmcache/v1/standalone/__main__.py +583 -0
- lmcache/v1/standalone/manager.py +80 -0
- lmcache/v1/standalone/standalone_service_factory.py +86 -0
- lmcache/v1/storage_backend/__init__.py +313 -0
- lmcache/v1/storage_backend/abstract_backend.py +445 -0
- lmcache/v1/storage_backend/audit_backend.py +233 -0
- lmcache/v1/storage_backend/batched_message_sender.py +222 -0
- lmcache/v1/storage_backend/cache_policy/__init__.py +45 -0
- lmcache/v1/storage_backend/cache_policy/base_policy.py +87 -0
- lmcache/v1/storage_backend/cache_policy/fifo.py +58 -0
- lmcache/v1/storage_backend/cache_policy/lfu.py +105 -0
- lmcache/v1/storage_backend/cache_policy/lru.py +81 -0
- lmcache/v1/storage_backend/cache_policy/mru.py +61 -0
- lmcache/v1/storage_backend/connector/__init__.py +443 -0
- lmcache/v1/storage_backend/connector/audit_adapter.py +77 -0
- lmcache/v1/storage_backend/connector/audit_connector.py +320 -0
- lmcache/v1/storage_backend/connector/base_connector.py +379 -0
- lmcache/v1/storage_backend/connector/blackhole_adapter.py +21 -0
- lmcache/v1/storage_backend/connector/blackhole_connector.py +37 -0
- lmcache/v1/storage_backend/connector/eic_adapter.py +31 -0
- lmcache/v1/storage_backend/connector/eic_connector.py +757 -0
- lmcache/v1/storage_backend/connector/external_adapter.py +79 -0
- lmcache/v1/storage_backend/connector/fs_adapter.py +51 -0
- lmcache/v1/storage_backend/connector/fs_connector.py +403 -0
- lmcache/v1/storage_backend/connector/infinistore_adapter.py +56 -0
- lmcache/v1/storage_backend/connector/infinistore_connector.py +177 -0
- lmcache/v1/storage_backend/connector/instrumented_connector.py +219 -0
- lmcache/v1/storage_backend/connector/lm_adapter.py +31 -0
- lmcache/v1/storage_backend/connector/lm_connector.py +176 -0
- lmcache/v1/storage_backend/connector/mock_adapter.py +57 -0
- lmcache/v1/storage_backend/connector/mock_connector.py +349 -0
- lmcache/v1/storage_backend/connector/mooncakestore_adapter.py +43 -0
- lmcache/v1/storage_backend/connector/mooncakestore_connector.py +614 -0
- lmcache/v1/storage_backend/connector/redis_adapter.py +181 -0
- lmcache/v1/storage_backend/connector/redis_connector.py +828 -0
- lmcache/v1/storage_backend/connector/s3_adapter.py +59 -0
- lmcache/v1/storage_backend/connector/s3_connector.py +699 -0
- lmcache/v1/storage_backend/connector/sagemaker_hyperpod_adapter.py +233 -0
- lmcache/v1/storage_backend/connector/sagemaker_hyperpod_connector.py +987 -0
- lmcache/v1/storage_backend/connector/valkey_adapter.py +114 -0
- lmcache/v1/storage_backend/connector/valkey_connector.py +627 -0
- lmcache/v1/storage_backend/gds_backend.py +1199 -0
- lmcache/v1/storage_backend/job_executor/__init__.py +0 -0
- lmcache/v1/storage_backend/job_executor/base_executor.py +34 -0
- lmcache/v1/storage_backend/job_executor/pq_executor.py +235 -0
- lmcache/v1/storage_backend/local_cpu_backend.py +810 -0
- lmcache/v1/storage_backend/local_disk_backend.py +656 -0
- lmcache/v1/storage_backend/maru_backend.py +734 -0
- lmcache/v1/storage_backend/naive_serde/__init__.py +50 -0
- lmcache/v1/storage_backend/naive_serde/cachegen_basics.py +133 -0
- lmcache/v1/storage_backend/naive_serde/cachegen_decoder.py +135 -0
- lmcache/v1/storage_backend/naive_serde/cachegen_encoder.py +83 -0
- lmcache/v1/storage_backend/naive_serde/kivi_serde.py +22 -0
- lmcache/v1/storage_backend/naive_serde/naive_serde.py +18 -0
- lmcache/v1/storage_backend/naive_serde/serde.py +37 -0
- lmcache/v1/storage_backend/native_clients/connector_client_base.py +165 -0
- lmcache/v1/storage_backend/native_clients/resp_client.py +35 -0
- lmcache/v1/storage_backend/nixl_storage_backend.py +1400 -0
- lmcache/v1/storage_backend/p2p_backend.py +788 -0
- lmcache/v1/storage_backend/path_sharder.py +117 -0
- lmcache/v1/storage_backend/pd_backend.py +646 -0
- lmcache/v1/storage_backend/plugins/dax_backend.py +1443 -0
- lmcache/v1/storage_backend/plugins/rust_raw_block_backend.py +1361 -0
- lmcache/v1/storage_backend/remote_backend.py +624 -0
- lmcache/v1/storage_backend/resp_client.py +227 -0
- lmcache/v1/storage_backend/storage_backend_listener.py +19 -0
- lmcache/v1/storage_backend/storage_manager.py +1352 -0
- lmcache/v1/system_detection.py +110 -0
- lmcache/v1/token_database.py +551 -0
- lmcache/v1/transfer_channel/__init__.py +83 -0
- lmcache/v1/transfer_channel/abstract.py +285 -0
- lmcache/v1/transfer_channel/mock_memory_channel.py +156 -0
- lmcache/v1/transfer_channel/nixl_channel.py +639 -0
- lmcache/v1/transfer_channel/py_socket_channel.py +260 -0
- lmcache/v1/transfer_channel/transfer_utils.py +63 -0
- lmcache/v1/utils/__init__.py +1 -0
- lmcache/v1/utils/bloom_filter.py +109 -0
- lmcache/v1/utils/cache_utils.py +125 -0
- lmcache_cli-0.4.5.dev0.dist-info/METADATA +185 -0
- lmcache_cli-0.4.5.dev0.dist-info/RECORD +399 -0
- lmcache_cli-0.4.5.dev0.dist-info/WHEEL +5 -0
- lmcache_cli-0.4.5.dev0.dist-info/entry_points.txt +2 -0
- lmcache_cli-0.4.5.dev0.dist-info/licenses/LICENSE +201 -0
- lmcache_cli-0.4.5.dev0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""
|
|
3
|
+
L2 adapter factory with lazy module loading.
|
|
4
|
+
|
|
5
|
+
Built-in adapter modules are auto-discovered via
|
|
6
|
+
``pkgutil`` but only imported when their adapter type
|
|
7
|
+
is actually requested. To add a new built-in adapter,
|
|
8
|
+
simply create a new ``*_l2_adapter.py`` module in this
|
|
9
|
+
directory -- **no other changes are needed**.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
# Standard
|
|
13
|
+
import pkgutil
|
|
14
|
+
|
|
15
|
+
# First Party
|
|
16
|
+
from lmcache.v1.distributed.internal_api import L1MemoryDesc
|
|
17
|
+
from lmcache.v1.distributed.l2_adapters.base import (
|
|
18
|
+
L2AdapterInterface,
|
|
19
|
+
)
|
|
20
|
+
from lmcache.v1.distributed.l2_adapters.config import (
|
|
21
|
+
L2AdapterConfigBase,
|
|
22
|
+
)
|
|
23
|
+
from lmcache.v1.distributed.l2_adapters.factory import (
|
|
24
|
+
add_pending_module,
|
|
25
|
+
create_l2_adapter_from_registry,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
# ---------------------------------------------------------
|
|
29
|
+
# Auto-discover built-in adapter modules (not imported yet)
|
|
30
|
+
# Convention: any ``*_l2_adapter`` submodule is eligible.
|
|
31
|
+
# ---------------------------------------------------------
|
|
32
|
+
for _finder, _module_name, _ispkg in pkgutil.iter_modules(__path__):
|
|
33
|
+
if _module_name.endswith("_l2_adapter"):
|
|
34
|
+
add_pending_module(f"{__name__}.{_module_name}")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def create_l2_adapter(
|
|
38
|
+
config: L2AdapterConfigBase,
|
|
39
|
+
l1_memory_desc: L1MemoryDesc | None = None,
|
|
40
|
+
) -> L2AdapterInterface:
|
|
41
|
+
"""Create an L2 adapter from its config via the
|
|
42
|
+
factory registry.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
config: The adapter-specific config object.
|
|
46
|
+
l1_memory_desc: Descriptor of the L1 memory buffer,
|
|
47
|
+
required for adapters that register L1 memory
|
|
48
|
+
with an external backend (e.g. Nixl).
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
L2AdapterInterface: A new adapter instance.
|
|
52
|
+
|
|
53
|
+
Raises:
|
|
54
|
+
ValueError: If no factory is registered for
|
|
55
|
+
the config type.
|
|
56
|
+
"""
|
|
57
|
+
return create_l2_adapter_from_registry(
|
|
58
|
+
config,
|
|
59
|
+
l1_memory_desc=l1_memory_desc,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
__all__ = [
|
|
64
|
+
"L2AdapterInterface",
|
|
65
|
+
"L2AdapterConfigBase",
|
|
66
|
+
"create_l2_adapter",
|
|
67
|
+
]
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""
|
|
3
|
+
Interface for L2 adapters
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
# Future
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
# Standard
|
|
10
|
+
from abc import ABC, abstractmethod
|
|
11
|
+
from typing import TYPE_CHECKING
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
# First Party
|
|
15
|
+
from lmcache.native_storage_ops import Bitmap
|
|
16
|
+
|
|
17
|
+
# First Party
|
|
18
|
+
from lmcache.v1.distributed.api import ObjectKey
|
|
19
|
+
from lmcache.v1.distributed.internal_api import L2AdapterListener
|
|
20
|
+
from lmcache.v1.memory_management import MemoryObj
|
|
21
|
+
|
|
22
|
+
L2TaskId = int
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class L2AdapterInterface(ABC):
|
|
26
|
+
"""
|
|
27
|
+
The abstracted interface for L2 I/O adapters.
|
|
28
|
+
|
|
29
|
+
The L2 I/O adapter mainly provides 3 main functionalities with non-blocking
|
|
30
|
+
primitives:
|
|
31
|
+
1. Store: store a batch of memory objects associated with a batch of keys.
|
|
32
|
+
2. Lookup and lock: look up and lock a batch of objects by the given keys.
|
|
33
|
+
will also try to 'lock' the objects to prevent being evicted before
|
|
34
|
+
loading them to L1.
|
|
35
|
+
3. Load: load a batch of objects by the given keys. The load operation is
|
|
36
|
+
not guaranteed to succeed, and the caller should check the return value.
|
|
37
|
+
In most of cases, it should be likely to succeed if the objects are locked.
|
|
38
|
+
|
|
39
|
+
Note that the store and the load operation are pre-provided with the data buffer
|
|
40
|
+
(i.e., memory objects), which is managed by the caller (L2 controller). The L2
|
|
41
|
+
adapter is not supposed to manage the lifecycle of the memory objects.
|
|
42
|
+
|
|
43
|
+
The non-blocking interface is designed as follows:
|
|
44
|
+
1. Submit task
|
|
45
|
+
2. Query the completed tasks (either pop all the completed tasks or query
|
|
46
|
+
a specific task by its id)
|
|
47
|
+
3. Use event fd to signal the completion of the tasks. The event fd will be
|
|
48
|
+
handled by the caller (L2 controller). Note that the event fd will be
|
|
49
|
+
closed by the `close()` function.
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
Error handling:
|
|
53
|
+
1. For store operation, we only provide a coarse-grained error handling, which
|
|
54
|
+
means that we only report the error at the task level. If a store task fails,
|
|
55
|
+
we will report the failure of the whole task, instead of reporting the failure
|
|
56
|
+
of each key-object pair in the task. The caller can choose to retry the failed
|
|
57
|
+
task or not.
|
|
58
|
+
2. For both lookup and load operations, we will return a bitmap indicating the
|
|
59
|
+
success or failure of each key-object pair in the task.
|
|
60
|
+
|
|
61
|
+
Thread-safe:
|
|
62
|
+
The L2 adapter is designed to be called by a 2 controller threads (store controller
|
|
63
|
+
and prefetch controller), therefore, it needs to be thread-safe.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
def __init__(self):
|
|
67
|
+
self._listeners: list[L2AdapterListener] = []
|
|
68
|
+
|
|
69
|
+
#####################
|
|
70
|
+
# Event Fd Interface
|
|
71
|
+
#####################
|
|
72
|
+
|
|
73
|
+
# IMPORTANT: Each of the three event fd methods below MUST return a
|
|
74
|
+
# distinct file descriptor. The store controller and prefetch controller
|
|
75
|
+
# build fd-to-adapter lookup maps; if any two methods return the same fd
|
|
76
|
+
# (within one adapter or across adapters), poll-based dispatch will
|
|
77
|
+
# silently misroute events.
|
|
78
|
+
|
|
79
|
+
@abstractmethod
|
|
80
|
+
def get_store_event_fd(self) -> int:
|
|
81
|
+
"""
|
|
82
|
+
Get the event fd for store operation, which will be signaled on the
|
|
83
|
+
completion of the store tasks.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
int: the event fd for store operation.
|
|
87
|
+
|
|
88
|
+
Note:
|
|
89
|
+
Must be distinct from the lookup and load event fds of this
|
|
90
|
+
adapter, and from the event fds of all other adapters.
|
|
91
|
+
"""
|
|
92
|
+
pass
|
|
93
|
+
|
|
94
|
+
@abstractmethod
|
|
95
|
+
def get_lookup_and_lock_event_fd(self) -> int:
|
|
96
|
+
"""
|
|
97
|
+
Get the event fd for lookup and lock operation, which will be signaled
|
|
98
|
+
on the completion of the lookup and lock tasks.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
int: the event fd for lookup and lock operation.
|
|
102
|
+
|
|
103
|
+
Note:
|
|
104
|
+
Must be distinct from the store and load event fds of this
|
|
105
|
+
adapter, and from the event fds of all other adapters.
|
|
106
|
+
"""
|
|
107
|
+
pass
|
|
108
|
+
|
|
109
|
+
@abstractmethod
|
|
110
|
+
def get_load_event_fd(self) -> int:
|
|
111
|
+
"""
|
|
112
|
+
Get the event fd for load operation, which will be signaled on the completion
|
|
113
|
+
of the load tasks.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
int: the event fd for load operation.
|
|
117
|
+
|
|
118
|
+
Note:
|
|
119
|
+
Must be distinct from the store and lookup event fds of this
|
|
120
|
+
adapter, and from the event fds of all other adapters.
|
|
121
|
+
"""
|
|
122
|
+
pass
|
|
123
|
+
|
|
124
|
+
#####################
|
|
125
|
+
# Store Interface
|
|
126
|
+
#####################
|
|
127
|
+
|
|
128
|
+
@abstractmethod
|
|
129
|
+
def submit_store_task(
|
|
130
|
+
self,
|
|
131
|
+
keys: list[ObjectKey],
|
|
132
|
+
objects: list[MemoryObj],
|
|
133
|
+
) -> L2TaskId:
|
|
134
|
+
"""
|
|
135
|
+
Submit a store task to store a batch of memory objects associated with
|
|
136
|
+
a batch of keys.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
keys (list[ObjectKey]): the list of keys to be stored.
|
|
140
|
+
objects (list[MemoryObj]): the list of memory objects to be stored.
|
|
141
|
+
The length of the objects list should be the same as the length of
|
|
142
|
+
the keys list.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
L2TaskId: the task id of the submitted store task.
|
|
146
|
+
"""
|
|
147
|
+
pass
|
|
148
|
+
|
|
149
|
+
@abstractmethod
|
|
150
|
+
def pop_completed_store_tasks(self) -> dict[L2TaskId, bool]:
|
|
151
|
+
"""
|
|
152
|
+
Pop all the completed store tasks with a flag indicating
|
|
153
|
+
whether the task is successful or not.
|
|
154
|
+
|
|
155
|
+
Returns:
|
|
156
|
+
dict[L2TaskId, bool]: a dictionary mapping the task id to a boolean flag
|
|
157
|
+
indicating whether the task is successful or not. True means
|
|
158
|
+
successful, and False means failed.
|
|
159
|
+
"""
|
|
160
|
+
pass
|
|
161
|
+
|
|
162
|
+
#####################
|
|
163
|
+
# Lookup and Lock Interface
|
|
164
|
+
#####################
|
|
165
|
+
|
|
166
|
+
@abstractmethod
|
|
167
|
+
def submit_lookup_and_lock_task(
|
|
168
|
+
self,
|
|
169
|
+
keys: list[ObjectKey],
|
|
170
|
+
) -> L2TaskId:
|
|
171
|
+
"""
|
|
172
|
+
Submit a lookup and lock task to look up and lock a batch of objects
|
|
173
|
+
by the given keys.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
keys (list[ObjectKey]): the list of keys to be looked up and locked.
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
L2TaskId: the task id of the submitted lookup and lock task.
|
|
180
|
+
"""
|
|
181
|
+
pass
|
|
182
|
+
|
|
183
|
+
@abstractmethod
|
|
184
|
+
def query_lookup_and_lock_result(self, task_id: L2TaskId) -> Bitmap | None:
|
|
185
|
+
"""
|
|
186
|
+
Non-blockingly query the result of a lookup and lock task by its task id.
|
|
187
|
+
The result is a bitmap indicating the success or failure of each key-object
|
|
188
|
+
pair in the task.
|
|
189
|
+
|
|
190
|
+
For a single task id, this function will ONLY return a non-None value ONCE.
|
|
191
|
+
(Which means this function is not idempotent)
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
task_id (L2TaskId): the task id of the lookup and lock task.
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
Optional[Bitmap]: a bitmap indicating the success or failure of each
|
|
198
|
+
key-object pair in the task. 1 means successful, and 0 means failed.
|
|
199
|
+
None is returned when the lookup and lock task is not completed.
|
|
200
|
+
"""
|
|
201
|
+
pass
|
|
202
|
+
|
|
203
|
+
@abstractmethod
|
|
204
|
+
def submit_unlock(
|
|
205
|
+
self,
|
|
206
|
+
keys: list[ObjectKey],
|
|
207
|
+
) -> None:
|
|
208
|
+
"""
|
|
209
|
+
Submit an unlock task to unlock a batch of objects by the given keys.
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
keys (list[ObjectKey]): the list of keys to be unlocked.
|
|
213
|
+
|
|
214
|
+
Note:
|
|
215
|
+
This function does not return any task id, meaning that the caller
|
|
216
|
+
assumes the unlock operation will be eventually successful, and will
|
|
217
|
+
NEVER retry.
|
|
218
|
+
Therefore, the implementation MUST make sure that the unlock operation
|
|
219
|
+
is successful (i.e., have error handling and retry mechanism if needed).
|
|
220
|
+
"""
|
|
221
|
+
pass
|
|
222
|
+
|
|
223
|
+
#####################
|
|
224
|
+
# Load Interface
|
|
225
|
+
######################
|
|
226
|
+
|
|
227
|
+
@abstractmethod
|
|
228
|
+
def submit_load_task(
|
|
229
|
+
self,
|
|
230
|
+
keys: list[ObjectKey],
|
|
231
|
+
objects: list[MemoryObj],
|
|
232
|
+
) -> L2TaskId:
|
|
233
|
+
"""
|
|
234
|
+
Submit a load task to load a batch of objects by the given keys. The load
|
|
235
|
+
operation is not guaranteed to succeed, and the caller should check the
|
|
236
|
+
return value.
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
keys (list[ObjectKey]): the list of keys to be loaded.
|
|
240
|
+
objects (list[MemoryObj]): the list of memory objects as the load buffer.
|
|
241
|
+
The L2 adapter will write the loaded data to the memory buffer provided
|
|
242
|
+
by the caller. The caller is responsible for managing the lifecycle of
|
|
243
|
+
the memory objects, and should make sure that the memory buffer is valid
|
|
244
|
+
until the load task is completed.
|
|
245
|
+
The length of the objects list should be the same as the length of the
|
|
246
|
+
keys list.
|
|
247
|
+
|
|
248
|
+
Returns:
|
|
249
|
+
L2TaskId: the task id of the submitted load task.
|
|
250
|
+
"""
|
|
251
|
+
pass
|
|
252
|
+
|
|
253
|
+
@abstractmethod
|
|
254
|
+
def query_load_result(self, task_id: L2TaskId) -> Bitmap | None:
|
|
255
|
+
"""
|
|
256
|
+
Non-blockingly query the result of a load task by its task id. The result
|
|
257
|
+
is a bitmap indicating the success or failure of each key-object pair in
|
|
258
|
+
the task.
|
|
259
|
+
|
|
260
|
+
For a single task id, this function will ONLY return a non-None value ONCE.
|
|
261
|
+
(Which means this function is not idempotent)
|
|
262
|
+
|
|
263
|
+
Args:
|
|
264
|
+
task_id (L2TaskId): the task id of the load task.
|
|
265
|
+
|
|
266
|
+
Returns:
|
|
267
|
+
Optional[Bitmap]: a bitmap indicating the success or failure of each
|
|
268
|
+
key-object pair in the task. 1 means successful, and 0 means failed.
|
|
269
|
+
None is returned when the load task is not completed.
|
|
270
|
+
"""
|
|
271
|
+
pass
|
|
272
|
+
|
|
273
|
+
#####################
|
|
274
|
+
# Listener Interface
|
|
275
|
+
#####################
|
|
276
|
+
|
|
277
|
+
def register_listener(self, listener: L2AdapterListener) -> None:
|
|
278
|
+
"""Register a listener to receive L2 adapter events."""
|
|
279
|
+
self._listeners.append(listener)
|
|
280
|
+
|
|
281
|
+
def _notify_keys_stored(self, keys: list[ObjectKey]) -> None:
|
|
282
|
+
for listener in self._listeners:
|
|
283
|
+
listener.on_l2_keys_stored(keys)
|
|
284
|
+
|
|
285
|
+
def _notify_keys_accessed(self, keys: list[ObjectKey]) -> None:
|
|
286
|
+
for listener in self._listeners:
|
|
287
|
+
listener.on_l2_keys_accessed(keys)
|
|
288
|
+
|
|
289
|
+
def _notify_keys_deleted(self, keys: list[ObjectKey]) -> None:
|
|
290
|
+
for listener in self._listeners:
|
|
291
|
+
listener.on_l2_keys_deleted(keys)
|
|
292
|
+
|
|
293
|
+
#####################
|
|
294
|
+
# Eviction Interface
|
|
295
|
+
#####################
|
|
296
|
+
|
|
297
|
+
def delete(self, keys: list[ObjectKey]) -> None:
|
|
298
|
+
"""
|
|
299
|
+
Delete a batch of objects from L2 storage.
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
keys (list[ObjectKey]): The keys of the objects to delete.
|
|
303
|
+
|
|
304
|
+
Note:
|
|
305
|
+
Implementations should fire on_l2_keys_deleted on registered
|
|
306
|
+
L2AdapterListeners once the deletion completes.
|
|
307
|
+
|
|
308
|
+
The default implementation is a no-op. Subclasses that support
|
|
309
|
+
eviction should override this method.
|
|
310
|
+
"""
|
|
311
|
+
return None
|
|
312
|
+
|
|
313
|
+
def get_usage(self) -> tuple[float, float]:
|
|
314
|
+
"""
|
|
315
|
+
Return the current L2 storage utilization.
|
|
316
|
+
|
|
317
|
+
Returns:
|
|
318
|
+
tuple[float, float]: A pair
|
|
319
|
+
``(current_usage, usage_after_ongoing_eviction)`` where each
|
|
320
|
+
value is in the range [0.0, 1.0].
|
|
321
|
+
|
|
322
|
+
- ``current_usage``: fraction of total L2 capacity currently
|
|
323
|
+
occupied (bytes used / total bytes).
|
|
324
|
+
- ``usage_after_ongoing_eviction``: estimated fraction once all
|
|
325
|
+
in-flight deletes/evictions complete
|
|
326
|
+
((bytes used - bytes being deleted) / total bytes).
|
|
327
|
+
|
|
328
|
+
The default implementation returns ``(-1.0, -1.0)`` to indicate
|
|
329
|
+
that usage tracking is not supported. Subclasses that support
|
|
330
|
+
eviction should override this method.
|
|
331
|
+
"""
|
|
332
|
+
return (-1.0, -1.0)
|
|
333
|
+
|
|
334
|
+
#####################
|
|
335
|
+
# Cleanup Interface
|
|
336
|
+
#####################
|
|
337
|
+
|
|
338
|
+
@abstractmethod
|
|
339
|
+
def close(self) -> None:
|
|
340
|
+
"""
|
|
341
|
+
Close the L2 adapter and release all the resources. After calling this function,
|
|
342
|
+
the L2 adapter should not be used anymore.
|
|
343
|
+
"""
|
|
344
|
+
pass
|
|
345
|
+
|
|
346
|
+
#####################
|
|
347
|
+
# Status Interface
|
|
348
|
+
#####################
|
|
349
|
+
|
|
350
|
+
def report_status(self) -> dict:
|
|
351
|
+
"""
|
|
352
|
+
Return a status dict for this adapter.
|
|
353
|
+
|
|
354
|
+
Must include at least ``is_healthy: bool``.
|
|
355
|
+
Subclasses should override this with adapter-specific metrics.
|
|
356
|
+
"""
|
|
357
|
+
return {
|
|
358
|
+
"is_healthy": True,
|
|
359
|
+
"extra_warning": "report_status is not implemented and runs default impl",
|
|
360
|
+
}
|