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,10 @@
|
|
|
1
|
+
"""Constants for LMCache Controller ZMQ Benchmark"""
|
|
2
|
+
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
# ZMQ socket configuration
|
|
6
|
+
DEFAULT_SEND_TIMEOUT_MS = 5000
|
|
7
|
+
DEFAULT_RECV_TIMEOUT_MS = 5000
|
|
8
|
+
DEFAULT_SEND_HWM = 10000
|
|
9
|
+
DEFAULT_BATCH_SEND_SIZE = 50
|
|
10
|
+
DEFAULT_OP_DISTRIBUTION_BASE = 1000
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""Operation handlers with dynamic discovery and registration"""
|
|
2
|
+
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
# Standard
|
|
6
|
+
from typing import Dict
|
|
7
|
+
import importlib
|
|
8
|
+
import inspect
|
|
9
|
+
import pkgutil
|
|
10
|
+
|
|
11
|
+
# Local
|
|
12
|
+
from .base import OperationHandler
|
|
13
|
+
|
|
14
|
+
# Operation handler registry
|
|
15
|
+
OPERATION_HANDLERS: Dict[str, OperationHandler] = {}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _discover_and_register_handlers():
|
|
19
|
+
"""Dynamically discover and register all operation handlers"""
|
|
20
|
+
# Get the current package
|
|
21
|
+
package = __package__
|
|
22
|
+
package_path = __path__
|
|
23
|
+
|
|
24
|
+
# Iterate through all modules in the handlers package
|
|
25
|
+
for _, module_name, _ in pkgutil.iter_modules(package_path):
|
|
26
|
+
# Skip base module
|
|
27
|
+
if module_name == "base":
|
|
28
|
+
continue
|
|
29
|
+
|
|
30
|
+
# Import the module
|
|
31
|
+
module = importlib.import_module("." + module_name, package=package)
|
|
32
|
+
|
|
33
|
+
# Find all classes that inherit from OperationHandler
|
|
34
|
+
for name, obj in inspect.getmembers(module, inspect.isclass):
|
|
35
|
+
if (
|
|
36
|
+
issubclass(obj, OperationHandler)
|
|
37
|
+
and obj is not OperationHandler
|
|
38
|
+
and not inspect.isabstract(obj)
|
|
39
|
+
):
|
|
40
|
+
# Instantiate and register the handler
|
|
41
|
+
handler = obj()
|
|
42
|
+
OPERATION_HANDLERS[handler.operation_name] = handler
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# Auto-discover and register handlers on import
|
|
46
|
+
_discover_and_register_handlers()
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""Admit operation handler"""
|
|
2
|
+
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
# Standard
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
7
|
+
import random
|
|
8
|
+
|
|
9
|
+
# First Party
|
|
10
|
+
from lmcache.v1.cache_controller.message import (
|
|
11
|
+
BatchedKVOperationMsg,
|
|
12
|
+
KVOpEvent,
|
|
13
|
+
OpType,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
# Local
|
|
18
|
+
from ..benchmark import TestData, ZMQControllerBenchmark
|
|
19
|
+
|
|
20
|
+
# Local
|
|
21
|
+
from .base import OperationHandler
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class AdmitHandler(OperationHandler):
|
|
25
|
+
"""Handler for admit operations"""
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def operation_name(self) -> str:
|
|
29
|
+
return "admit"
|
|
30
|
+
|
|
31
|
+
def create_message(
|
|
32
|
+
self, benchmark: "ZMQControllerBenchmark", test_data: "TestData"
|
|
33
|
+
) -> Any:
|
|
34
|
+
instance = random.choice(test_data.instances)
|
|
35
|
+
worker = random.choice(test_data.workers)
|
|
36
|
+
location = random.choice(test_data.locations)
|
|
37
|
+
|
|
38
|
+
operations = []
|
|
39
|
+
for _ in range(benchmark.config.batch_size):
|
|
40
|
+
key = random.choice(test_data.keys)
|
|
41
|
+
seq_num = benchmark.get_next_sequence_number(instance, worker, location)
|
|
42
|
+
operations.append(KVOpEvent(op_type=OpType.ADMIT, key=key, seq_num=seq_num))
|
|
43
|
+
|
|
44
|
+
return BatchedKVOperationMsg(
|
|
45
|
+
instance_id=instance,
|
|
46
|
+
worker_id=worker,
|
|
47
|
+
location=location,
|
|
48
|
+
operations=operations,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
def get_message_count(self, benchmark: "ZMQControllerBenchmark") -> int:
|
|
52
|
+
return benchmark.config.batch_size
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Base handler class for benchmark operations (Strategy Pattern)"""
|
|
2
|
+
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
# Standard
|
|
6
|
+
from abc import ABC, abstractmethod
|
|
7
|
+
from enum import Enum, auto
|
|
8
|
+
from typing import TYPE_CHECKING, Any
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
# Local
|
|
12
|
+
from ..benchmark import TestData, ZMQControllerBenchmark
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SocketType(Enum):
|
|
16
|
+
"""Socket type for benchmark operations"""
|
|
17
|
+
|
|
18
|
+
PUSH = auto() # PUSH socket for fire-and-forget messages
|
|
19
|
+
DEALER = auto() # DEALER socket for async request-reply messages
|
|
20
|
+
HEARTBEAT = auto() # Dedicated heartbeat DEALER socket
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class OperationHandler(ABC):
|
|
24
|
+
"""Base class for benchmark operation handlers (Strategy Pattern)"""
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
@abstractmethod
|
|
28
|
+
def operation_name(self) -> str:
|
|
29
|
+
"""Return the operation name for registration"""
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
@abstractmethod
|
|
33
|
+
def create_message(
|
|
34
|
+
self, benchmark: "ZMQControllerBenchmark", test_data: "TestData"
|
|
35
|
+
) -> Any:
|
|
36
|
+
"""Create a message for this operation"""
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
@abstractmethod
|
|
40
|
+
def get_message_count(self, benchmark: "ZMQControllerBenchmark") -> int:
|
|
41
|
+
"""Get the number of messages in a single operation"""
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def socket_type(self) -> SocketType:
|
|
46
|
+
"""Return the socket type for this operation (default: PUSH)"""
|
|
47
|
+
return SocketType.PUSH
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Deregister operation handler"""
|
|
2
|
+
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
# Standard
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
7
|
+
import random
|
|
8
|
+
|
|
9
|
+
# First Party
|
|
10
|
+
from lmcache.v1.cache_controller.message import DeRegisterMsg
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
# Local
|
|
14
|
+
from ..benchmark import TestData, ZMQControllerBenchmark
|
|
15
|
+
|
|
16
|
+
# Local
|
|
17
|
+
from .base import OperationHandler
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class DeregisterHandler(OperationHandler):
|
|
21
|
+
"""Handler for deregister operations"""
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def operation_name(self) -> str:
|
|
25
|
+
return "deregister"
|
|
26
|
+
|
|
27
|
+
def create_message(
|
|
28
|
+
self, benchmark: "ZMQControllerBenchmark", test_data: "TestData"
|
|
29
|
+
) -> Any:
|
|
30
|
+
instance = random.choice(test_data.instances)
|
|
31
|
+
worker = random.choice(test_data.workers)
|
|
32
|
+
ip, port = self._generate_random_endpoint()
|
|
33
|
+
|
|
34
|
+
return DeRegisterMsg(
|
|
35
|
+
instance_id=instance,
|
|
36
|
+
worker_id=worker,
|
|
37
|
+
ip=ip,
|
|
38
|
+
port=port,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
def get_message_count(self, benchmark: "ZMQControllerBenchmark") -> int:
|
|
42
|
+
return 1
|
|
43
|
+
|
|
44
|
+
@staticmethod
|
|
45
|
+
def _generate_random_endpoint():
|
|
46
|
+
"""Generate random IP and port for test messages"""
|
|
47
|
+
ip = "192.168.%d.%d" % (random.randint(1, 255), random.randint(1, 255))
|
|
48
|
+
port = random.randint(10000, 60000)
|
|
49
|
+
return ip, port
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""Evict operation handler"""
|
|
2
|
+
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
# Standard
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
7
|
+
import random
|
|
8
|
+
|
|
9
|
+
# First Party
|
|
10
|
+
from lmcache.v1.cache_controller.message import (
|
|
11
|
+
BatchedKVOperationMsg,
|
|
12
|
+
KVOpEvent,
|
|
13
|
+
OpType,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
# Local
|
|
18
|
+
from ..benchmark import TestData, ZMQControllerBenchmark
|
|
19
|
+
|
|
20
|
+
# Local
|
|
21
|
+
from .base import OperationHandler
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class EvictHandler(OperationHandler):
|
|
25
|
+
"""Handler for evict operations"""
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def operation_name(self) -> str:
|
|
29
|
+
return "evict"
|
|
30
|
+
|
|
31
|
+
def create_message(
|
|
32
|
+
self, benchmark: "ZMQControllerBenchmark", test_data: "TestData"
|
|
33
|
+
) -> Any:
|
|
34
|
+
instance = random.choice(test_data.instances)
|
|
35
|
+
worker = random.choice(test_data.workers)
|
|
36
|
+
location = random.choice(test_data.locations)
|
|
37
|
+
|
|
38
|
+
operations = []
|
|
39
|
+
for _ in range(benchmark.config.batch_size):
|
|
40
|
+
key = random.choice(test_data.keys)
|
|
41
|
+
seq_num = benchmark.get_next_sequence_number(instance, worker, location)
|
|
42
|
+
operations.append(KVOpEvent(op_type=OpType.EVICT, key=key, seq_num=seq_num))
|
|
43
|
+
|
|
44
|
+
return BatchedKVOperationMsg(
|
|
45
|
+
instance_id=instance,
|
|
46
|
+
worker_id=worker,
|
|
47
|
+
location=location,
|
|
48
|
+
operations=operations,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
def get_message_count(self, benchmark: "ZMQControllerBenchmark") -> int:
|
|
52
|
+
return benchmark.config.batch_size
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Heartbeat operation handler"""
|
|
2
|
+
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
# Standard
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
7
|
+
import random
|
|
8
|
+
|
|
9
|
+
# First Party
|
|
10
|
+
from lmcache.v1.cache_controller.message import HeartbeatMsg
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
# Local
|
|
14
|
+
from ..benchmark import TestData, ZMQControllerBenchmark
|
|
15
|
+
|
|
16
|
+
# Local
|
|
17
|
+
from .base import OperationHandler, SocketType
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class HeartbeatHandler(OperationHandler):
|
|
21
|
+
"""Handler for heartbeat operations (dedicated heartbeat socket)"""
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def operation_name(self) -> str:
|
|
25
|
+
return "heartbeat"
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def socket_type(self) -> SocketType:
|
|
29
|
+
return SocketType.HEARTBEAT
|
|
30
|
+
|
|
31
|
+
def create_message(
|
|
32
|
+
self, benchmark: "ZMQControllerBenchmark", test_data: "TestData"
|
|
33
|
+
) -> Any:
|
|
34
|
+
instance = random.choice(test_data.instances)
|
|
35
|
+
worker = random.choice(test_data.workers)
|
|
36
|
+
ip, port = self._generate_random_endpoint()
|
|
37
|
+
peer_ip, peer_port = self._generate_random_endpoint()
|
|
38
|
+
peer_init_url = "tcp://%s:%d" % (peer_ip, peer_port)
|
|
39
|
+
|
|
40
|
+
return HeartbeatMsg(
|
|
41
|
+
instance_id=instance,
|
|
42
|
+
worker_id=worker,
|
|
43
|
+
ip=ip,
|
|
44
|
+
port=port,
|
|
45
|
+
peer_init_url=peer_init_url,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
def get_message_count(self, benchmark: "ZMQControllerBenchmark") -> int:
|
|
49
|
+
return 1
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def _generate_random_endpoint():
|
|
53
|
+
"""Generate random IP and port for test messages"""
|
|
54
|
+
ip = "192.168.%d.%d" % (random.randint(1, 255), random.randint(1, 255))
|
|
55
|
+
port = random.randint(10000, 60000)
|
|
56
|
+
return ip, port
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""P2P lookup operation handler"""
|
|
2
|
+
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
# Standard
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
7
|
+
import random
|
|
8
|
+
|
|
9
|
+
# First Party
|
|
10
|
+
from lmcache.v1.cache_controller.message import BatchedP2PLookupMsg
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
# Local
|
|
14
|
+
from ..benchmark import TestData, ZMQControllerBenchmark
|
|
15
|
+
|
|
16
|
+
# Local
|
|
17
|
+
from .base import OperationHandler, SocketType
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class P2PLookupHandler(OperationHandler):
|
|
21
|
+
"""Handler for P2P lookup operations (uses DEALER-ROUTER socket)"""
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def operation_name(self) -> str:
|
|
25
|
+
return "p2p_lookup"
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def socket_type(self) -> SocketType:
|
|
29
|
+
return SocketType.DEALER
|
|
30
|
+
|
|
31
|
+
def create_message(
|
|
32
|
+
self, benchmark: "ZMQControllerBenchmark", test_data: "TestData"
|
|
33
|
+
) -> Any:
|
|
34
|
+
instance = random.choice(test_data.instances)
|
|
35
|
+
worker = random.choice(test_data.workers)
|
|
36
|
+
hashes = [
|
|
37
|
+
random.choice(test_data.keys) for _ in range(benchmark.config.num_hashes)
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
return BatchedP2PLookupMsg(
|
|
41
|
+
hashes=hashes,
|
|
42
|
+
instance_id=instance,
|
|
43
|
+
worker_id=worker,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
def get_message_count(self, benchmark: "ZMQControllerBenchmark") -> int:
|
|
47
|
+
return benchmark.config.num_hashes
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Register operation handler"""
|
|
2
|
+
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
# Standard
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
7
|
+
import random
|
|
8
|
+
|
|
9
|
+
# First Party
|
|
10
|
+
from lmcache.v1.cache_controller.message import RegisterMsg
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
# Local
|
|
14
|
+
from ..benchmark import TestData, ZMQControllerBenchmark
|
|
15
|
+
|
|
16
|
+
# Local
|
|
17
|
+
from .base import OperationHandler, SocketType
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class RegisterHandler(OperationHandler):
|
|
21
|
+
"""Handler for register operations (DEALER-ROUTER mode)"""
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def operation_name(self) -> str:
|
|
25
|
+
return "register"
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def socket_type(self) -> SocketType:
|
|
29
|
+
return SocketType.DEALER
|
|
30
|
+
|
|
31
|
+
def create_message(
|
|
32
|
+
self, benchmark: "ZMQControllerBenchmark", test_data: "TestData"
|
|
33
|
+
) -> Any:
|
|
34
|
+
instance = random.choice(test_data.instances)
|
|
35
|
+
worker = random.choice(test_data.workers)
|
|
36
|
+
ip, port = self._generate_random_endpoint()
|
|
37
|
+
peer_ip, peer_port = self._generate_random_endpoint()
|
|
38
|
+
peer_init_url = "tcp://%s:%d" % (peer_ip, peer_port)
|
|
39
|
+
|
|
40
|
+
return RegisterMsg(
|
|
41
|
+
instance_id=instance,
|
|
42
|
+
worker_id=worker,
|
|
43
|
+
ip=ip,
|
|
44
|
+
port=port,
|
|
45
|
+
peer_init_url=peer_init_url,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
def get_message_count(self, benchmark: "ZMQControllerBenchmark") -> int:
|
|
49
|
+
return 1
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def _generate_random_endpoint():
|
|
53
|
+
"""Generate random IP and port for test messages"""
|
|
54
|
+
ip = "192.168.%d.%d" % (random.randint(1, 255), random.randint(1, 255))
|
|
55
|
+
port = random.randint(10000, 60000)
|
|
56
|
+
return ip, port
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""
|
|
3
|
+
CLI tool to fetch and display the MP cache server status.
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
python -m lmcache.tools.mp_status_viewer [--url URL]
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
# Standard
|
|
10
|
+
import argparse
|
|
11
|
+
import json
|
|
12
|
+
import sys
|
|
13
|
+
import urllib.error
|
|
14
|
+
import urllib.request
|
|
15
|
+
|
|
16
|
+
HEALTHY = "\033[32mHEALTHY\033[0m"
|
|
17
|
+
UNHEALTHY = "\033[31mUNHEALTHY\033[0m"
|
|
18
|
+
|
|
19
|
+
INDENT = " "
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _health_str(is_healthy: bool) -> str:
|
|
23
|
+
return HEALTHY if is_healthy else UNHEALTHY
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _fmt_bytes(n: int) -> str:
|
|
27
|
+
if n >= 1024**3:
|
|
28
|
+
return f"{n / 1024**3:.2f} GB"
|
|
29
|
+
if n >= 1024**2:
|
|
30
|
+
return f"{n / 1024**2:.2f} MB"
|
|
31
|
+
if n >= 1024:
|
|
32
|
+
return f"{n / 1024:.2f} KB"
|
|
33
|
+
return f"{n} B"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _print_section(title: str, data: dict, depth: int = 0) -> None:
|
|
37
|
+
prefix = INDENT * depth
|
|
38
|
+
health = _health_str(data.get("is_healthy", True))
|
|
39
|
+
print(f"{prefix}{title} [{health}]")
|
|
40
|
+
|
|
41
|
+
for key, value in data.items():
|
|
42
|
+
if key == "is_healthy":
|
|
43
|
+
continue
|
|
44
|
+
if isinstance(value, dict):
|
|
45
|
+
_print_section(key, value, depth + 1)
|
|
46
|
+
elif isinstance(value, list) and value and isinstance(value[0], dict):
|
|
47
|
+
for i, item in enumerate(value):
|
|
48
|
+
_print_section(f"{key}[{i}]", item, depth + 1)
|
|
49
|
+
else:
|
|
50
|
+
display = value
|
|
51
|
+
if "bytes" in key.lower() and isinstance(value, (int, float)):
|
|
52
|
+
display = _fmt_bytes(int(value))
|
|
53
|
+
elif isinstance(value, float):
|
|
54
|
+
display = f"{value:.4f}"
|
|
55
|
+
print(f"{prefix}{INDENT}{key}: {display}")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def main() -> None:
|
|
59
|
+
parser = argparse.ArgumentParser(
|
|
60
|
+
description="Fetch and display LMCache MP server status"
|
|
61
|
+
)
|
|
62
|
+
parser.add_argument(
|
|
63
|
+
"--url",
|
|
64
|
+
type=str,
|
|
65
|
+
default="http://localhost:8000/api/status",
|
|
66
|
+
help="URL of the status endpoint",
|
|
67
|
+
)
|
|
68
|
+
parser.add_argument(
|
|
69
|
+
"--json",
|
|
70
|
+
action="store_true",
|
|
71
|
+
help="Output raw JSON instead of formatted view",
|
|
72
|
+
)
|
|
73
|
+
args = parser.parse_args()
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
req = urllib.request.Request(args.url)
|
|
77
|
+
with urllib.request.urlopen(req, timeout=10) as resp:
|
|
78
|
+
data = json.loads(resp.read().decode())
|
|
79
|
+
except urllib.error.URLError as e:
|
|
80
|
+
print(f"Error connecting to {args.url}: {e}", file=sys.stderr)
|
|
81
|
+
sys.exit(1)
|
|
82
|
+
|
|
83
|
+
if args.json:
|
|
84
|
+
print(json.dumps(data, indent=2))
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
print("=" * 60)
|
|
88
|
+
print(" LMCache MP Server Status")
|
|
89
|
+
print("=" * 60)
|
|
90
|
+
_print_section("engine", data)
|
|
91
|
+
print("=" * 60)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
if __name__ == "__main__":
|
|
95
|
+
main()
|