| description | Architecture overview: actor mesh, pod anatomy, message flow, gateway, crossplane, deployment patterns |
|---|
Asya is a Kubernetes-native async actor mesh. All components are designed around one principle: the message knows the way.
Actors communicate through queues. Each message carries its own route. Each actor scales independently via KEDA.
Every actor pod has a sidecar (Go) for queue polling and routing, a runtime (Python) for your handler, and an optional state proxy for virtual persistent memory.
Each actor pod has two injected containers:
- Sidecar (Go) β queue polling, envelope routing, retries, progress reporting, metrics
- Runtime (Python) β loads your handler, executes per envelope, communicates via Unix socket
Your handler sees only dict -> dict. The envelope structure, queue mechanics, and
routing are invisible to it.
The gateway bridges synchronous HTTP with the async mesh:
| Mode | Audience | Endpoints |
|---|---|---|
| api | External clients | /a2a/ (agents), /mcp (tools), /.well-known/agent.json |
| mesh | Sidecars (internal) | /mesh (progress, FLY events, final results) |
Both modes share a database (PostgreSQL) for task state. The gateway translates between HTTP request/response and the fire-and-forget queue-based mesh.
Crossplane manages the declarative lifecycle of actors. Each AsyncActor CRD creates:
- Message queue (SQS, RabbitMQ, or Pub/Sub)
- Deployment with sidecar + runtime containers rendered inline
- KEDA ScaledObject watching queue depth
Deleting an AsyncActor cascades to all three. No orphaned queues.
Crew actors handle framework-level concerns:
| Actor | Role |
|---|---|
x-sink |
Persists successful results, reports completion to gateway |
x-sump |
Terminal error collection, metrics, DLQ |
x-pause |
Checkpoints envelope to S3 for human-in-the-loop |
x-resume |
Restores checkpointed envelope, re-injects into mesh |
The state proxy gives actors virtual persistent
memory. Actors read/write /state/... paths using standard file I/O β the proxy
translates to S3, GCS, Redis, or NATS KV.
The flow compiler transforms Python control
flow (if/else, while, asyncio.gather) into flat actor execution graphs. Purely
additive β generates standard AsyncActor manifests.
- Client sends HTTP request to Gateway (or enqueues directly)
- Gateway creates task, injects envelope into first actor's queue
- Sidecar consumes envelope from queue
- Sidecar forwards payload to Runtime via Unix socket
- Runtime executes your handler, returns result
- Sidecar advances the route, sends envelope to next actor's queue
- Repeat 3-6 for each actor in
route.next - x-sink persists final result, reports status to gateway
- Gateway delivers result to client (blocking wait or SSE stream)
The core loop: Queue -> Sidecar -> Your Code -> Sidecar -> Next Queue
- Crossplane creates SQS queues via AWS Provider
- IAM via IRSA or Pod Identity for queue/S3 access
- Results stored in S3
- KEDA scales via SQS queue depth metrics
- See: AWS EKS Guide
- Crossplane creates Pub/Sub subscriptions via GCP Provider
- IAM via Workload Identity for Pub/Sub/GCS access
- Results stored in GCS
- KEDA scales via Pub/Sub subscription metrics
- See: GCP GKE Guide
- RabbitMQ or LocalStack SQS for transport
- MinIO (S3-compatible) for storage
- Username/password auth from K8s secrets
- See: Quickstart
- Envelope β message structure, routing (
prev/curr/next), status - Sidecar-Runtime β Unix socket framing, error handling
- Gateway API β A2A, MCP, mesh HTTP endpoints
- ABI Protocol β generator yield forms (GET, SET, FLY)
- AsyncActor CRD β full manifest reference
- Flow DSL β flow compilation semantics