DLSlime control-plane server (Redis-backed service registry and peer-agent coordinator)
Project description
dlslime-ctrl
dlslime-ctrl is the control plane for DLSlime microservice governance. It provides a Redis-backed registry for discoverable services, heartbeat-based liveness, scope-based isolation, PeerAgent coordination, RDMA memory-region lookup, and declarative peer topology management.
dlslime-ctrl intentionally treats services generically. A cache service, RPC worker, prefill service, decode service, router, or future DLSlime component all register through the same entity lifecycle API and put service-specific fields inside JSON metadata.
Responsibilities
| Area | Responsibility |
|---|---|
| Service registry | Register, discover, heartbeat, and unregister generic entities |
| Microservice governance | Track service kind, endpoint, metadata, resource hints, and TTL |
| Scope isolation | Partition Redis keys by scope so multiple jobs can share one dlslime-ctrl |
| PeerAgent control | Register PeerAgents, publish resource records, and clean stale state |
| RDMA metadata | Store and query memory-region metadata for remote access |
| Topology control | Store desired PeerAgent topology and push connection intents |
| Redis access | Expose the Redis address that remote DLSlime clients should use |
Concepts
Entity
An entity is a discoverable object managed by dlslime-ctrl. The default
entity_type is service.
{
"entity_type": "service",
"entity_id": "cache:0",
"kind": "cache",
"endpoint": {
"host": "127.0.0.1",
"port": 8765,
"protocol": "http"
},
"metadata": {
"p2p_host": "127.0.0.1",
"p2p_port": 8765
}
}
dlslime-ctrl stores the entity as JSON and does not interpret the contents of
endpoint, metadata, or resource beyond preserving them for discovery.
Kind
kind is the service category used for discovery and filtering. Examples:
cacherpc-workerprefilldecoderouter
Scope
scope is an optional namespace. When present, all Redis keys are prefixed with
{scope}:. This lets multiple jobs, tests, or applications share one dlslime-ctrl
and Redis instance without colliding.
Prerequisites
- Redis server
- Rust toolchain when building dlslime-ctrl from source
- Python 3.8+ when using the
dlslime-ctrlPython client package
Build
cd dlslime-ctrl
cargo build --release
# Build a Python wheel that includes the Rust dlslime-ctrl binary
maturin build --release
Run
# Default: Redis at redis://127.0.0.1:6379
cargo run --release -- server
# Specify Redis explicitly
cargo run --release -- server --redis-url redis://your-redis-host:6379
# Or use the environment
export DLSLIME_CTRL_REDIS_URL=redis://your-redis-host:6379
cargo run --release -- server
The HTTP server listens on http://0.0.0.0:4479 by default.
Background Lifecycle
dlslime-ctrl includes a service-style CLI:
pip install -e dlslime-ctrl/
dlslime-ctrl start
dlslime-ctrl status
dlslime-ctrl stop
Useful options:
dlslime-ctrl start --redis-url redis://your-redis-host:6379 --log-file /tmp/dlslime-ctrl.log
dlslime-ctrl server --host 0.0.0.0 --port 3000
dlslime-ctrl stop --force
Runtime metadata is stored under $DLSLIME_CTRL_RUNTIME_DIR, or
$XDG_RUNTIME_DIR/dlslime-ctrl, or /tmp/dlslime-ctrl.
API
Service Registry
| Endpoint | Description |
|---|---|
POST /register |
Register or refresh a generic entity |
POST /unregister |
Remove a registered entity |
POST /heartbeat |
Refresh an entity TTL |
POST /get_entity_info |
Fetch one entity by type and ID |
POST /list_entities |
List entities, optionally filtered by type and kind |
PeerAgent and RDMA
| Endpoint | Description |
|---|---|
POST /start_peer_agent |
Register a PeerAgent and return Redis information |
POST /query |
List PeerAgents visible in the scope |
POST /cleanup |
Clean PeerAgent state and notify peers |
POST /v1/desired_topology/:agent_id |
Set desired PeerAgent topology |
POST /register_mr |
Register a memory region |
POST /get_mr_info |
Query a remote memory region |
Utility
| Endpoint | Description |
|---|---|
POST /get_redis_address |
Return the Redis address remote clients should use |
GET / |
Health check |
Entity API Examples
Register a Cache Service
curl http://127.0.0.1:4479/register \
-H "Content-Type: application/json" \
-d '{
"entity_type": "service",
"entity_id": "cache:0",
"kind": "cache",
"endpoint": {
"host": "127.0.0.1",
"port": 8765,
"protocol": "http"
},
"metadata": {
"p2p_host": "127.0.0.1",
"p2p_port": 8765
},
"scope": "job-a"
}'
Register a ZMQ Service
curl http://127.0.0.1:4479/register \
-H "Content-Type: application/json" \
-d '{
"entity_id": "prefill:0",
"kind": "prefill",
"endpoint": {
"host": "10.0.0.2",
"port": 6001,
"protocol": "zmq"
},
"metadata": {
"world_size": 8,
"num_blocks": 15000,
"peer_addrs": ["10.0.0.2:5000"]
}
}'
entity_type defaults to service when omitted.
Heartbeat
curl http://127.0.0.1:4479/heartbeat \
-H "Content-Type: application/json" \
-d '{
"entity_type": "service",
"entity_id": "cache:0",
"scope": "job-a"
}'
Discover Cache Services
curl http://127.0.0.1:4479/list_entities \
-H "Content-Type: application/json" \
-d '{
"entity_type": "service",
"kind": "cache",
"scope": "job-a"
}'
Response:
{
"status": "ok",
"entities": [
{
"entity_type": "service",
"entity_id": "cache:0",
"id": "cache:0",
"kind": "cache",
"endpoint": {
"host": "127.0.0.1",
"port": 8765,
"protocol": "http"
},
"metadata": {
"p2p_host": "127.0.0.1",
"p2p_port": 8765
},
"resource": null
}
]
}
Python Client
The Python client lives in the dlslime package (see dlslime.ctrl.NanoCtrlClient).
from dlslime.ctrl import NanoCtrlClient
client = NanoCtrlClient("127.0.0.1:4479", scope="job-a")
client.check_connection()
def register_cache() -> bool:
return client.register(
"cache:0",
"cache",
endpoint={"host": "127.0.0.1", "port": 8765, "protocol": "http"},
metadata={"p2p_host": "127.0.0.1", "p2p_port": 8765},
)
if register_cache():
client.start_heartbeat(on_not_found=register_cache)
cache = client.get_entity_info("cache:0")
caches = client.list_entities(kind="cache")
client.stop()
Client Methods
| Method | Description |
|---|---|
register(entity_id, kind, endpoint=None, metadata=None, resource=None, entity_type="service") |
Register a generic entity |
unregister() |
Unregister the entity registered by this client |
heartbeat() |
Refresh the entity TTL |
start_heartbeat(interval=15.0, on_not_found=None, name="dlslime-ctrl-hb") |
Start background heartbeat |
stop_heartbeat(timeout=2.0) |
Stop background heartbeat |
stop(timeout=2.0) |
Stop heartbeat and unregister |
get_entity_info(entity_id, entity_type="service") |
Query one entity |
list_entities(entity_type="service", kind=None) |
List entities |
get_redis_url() |
Resolve Redis URL through dlslime-ctrl |
PeerAgent helpers are also available on the same client:
register_peer(...)cleanup_peer(agent_name)heartbeat_peer(agent_name)set_desired_topology(...)query_peers()
DLSlimeCache Registration
dlslime-cache start --ctrl ... registers itself as a generic service:
{
"entity_type": "service",
"entity_id": "cache:0",
"kind": "cache",
"endpoint": {
"host": "<advertised-host>",
"port": 8765,
"protocol": "http"
},
"metadata": {
"p2p_host": "<advertised-host>",
"p2p_port": 8765
}
}
Clients discover it with list_entities(kind="cache") or
get_entity_info("cache:0").
Redis Key Structure
With scope:
{scope}:{entity_type}:{entity_id}
{scope}:nano_meta:{entity_type}_revision
{scope}:nano_events:{entity_type}_update
{scope}:agent:{agent_id}
{scope}:mr:{agent_id}:{mr_name}
{scope}:spec:topology:{agent_id}
{scope}:stream:{agent_id}
{scope}:inbox:{agent_id}
Without scope, the same keys are used without the prefix, for example
service:cache:0.
Environment Variables
| Variable | Description |
|---|---|
DLSLIME_CTRL_REDIS_URL |
Redis URL used by dlslime-ctrl |
DLSLIME_CTRL_RUST_LOG |
Rust log level, default info |
REDIS_PUBLIC_ADDRESS |
Optional public Redis host:port returned to remote clients |
DLSLIME_CTRL_SCOPE |
Optional client-side scope used by DLSlime services |
Notes
- dlslime-ctrl is stateless; Redis is the source of truth.
- Registered entities expire if they stop heartbeating.
- Service-specific fields belong in
metadata; dlslime-ctrl should not grow kind-specific schemas. - Use
scopefor tests, multiple jobs, and multi-tenant deployments.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dlslime_ctrl-0.1.22-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: dlslime_ctrl-0.1.22-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 2.4 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e82ac6af2e5cbd5f244832603d61747526ca2b3728f4c86d024bded398e71743
|
|
| MD5 |
5c6c523dd31cca843c70b330f346971d
|
|
| BLAKE2b-256 |
f4245a97bca77a0fd2fe60ad242782044e056faa0e9f4d22648672a387dc5af8
|
Provenance
The following attestation bundles were made for dlslime_ctrl-0.1.22-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
pypi-publish.yml on DeepLink-org/DLSlime
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dlslime_ctrl-0.1.22-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
e82ac6af2e5cbd5f244832603d61747526ca2b3728f4c86d024bded398e71743 - Sigstore transparency entry: 1730331723
- Sigstore integration time:
-
Permalink:
DeepLink-org/DLSlime@68d6b3f15e69e5be98d8f9670a90bb7f94eac852 -
Branch / Tag:
refs/tags/v0.1.22 - Owner: https://github.com/DeepLink-org
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@68d6b3f15e69e5be98d8f9670a90bb7f94eac852 -
Trigger Event:
push
-
Statement type: