540e1c86a4
Input streams enable sending typed data to executing tasks from external
callers — backends, frontends, or other tasks. This unlocks interactive
use cases like approval UIs, cancel buttons, chat interfaces, and
human-in-the-loop AI workflows where the task needs to receive data
while running.
Three consumption patterns inside a task:
* `.wait()` — Suspend the task until data arrives (process freed, most
efficient)
* `.once()` — Wait for the next message (process stays alive)
* `.on()` — Subscribe to a continuous stream of messages
One send pattern from outside:
* `.send(runId, data)` — Send typed data to a specific run's input
stream
## User-facing API
### Define a typed input stream
```ts
import { streams, task } from "@trigger.dev/sdk";
const approval = streams.input<{ approved: boolean; reviewer: string }>({ id: "approval" });
```
### Consume inside a task
```ts
export const myTask = task({
id: "my-task",
run: async () => {
// Pattern 1: Suspend until data arrives (most efficient — frees the process)
const result = await approval.wait({ timeout: "5m" });
// Pattern 2: Wait for next message (process stays alive)
const data = await approval.once().unwrap();
// Pattern 3: Subscribe to multiple messages
approval.on((data) => { /* handle each message */ });
},
});
```
### Send from outside
```ts
// From a backend (using secret API key)
await approval.send(runId, { approved: true, reviewer: "alice" });
// From a frontend (using public JWT token from trigger response)
const { send } = useInputStreamSend("approval", runId, { accessToken });
send({ approved: true, reviewer: "alice" });
```
---------
Co-authored-by: Claude <noreply@anthropic.com>
233 lines
5.5 KiB
YAML
233 lines
5.5 KiB
YAML
version: "3"
|
|
|
|
volumes:
|
|
database-data:
|
|
database-data-alt:
|
|
redis-data:
|
|
clickhouse-data:
|
|
clickhouse-logs:
|
|
prometheus-data:
|
|
grafana-data:
|
|
|
|
networks:
|
|
app_network:
|
|
external: false
|
|
|
|
services:
|
|
database:
|
|
container_name: database
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile.postgres
|
|
restart: always
|
|
volumes:
|
|
- ${DB_VOLUME:-database-data}:/var/lib/postgresql/data/
|
|
environment:
|
|
POSTGRES_USER: postgres
|
|
POSTGRES_PASSWORD: postgres
|
|
POSTGRES_DB: postgres
|
|
networks:
|
|
- app_network
|
|
ports:
|
|
- 5432:5432
|
|
command:
|
|
- -c
|
|
- listen_addresses=*
|
|
- -c
|
|
- wal_level=logical
|
|
- -c
|
|
- shared_preload_libraries=pg_partman_bgw
|
|
|
|
redis:
|
|
container_name: redis
|
|
image: redis:7
|
|
restart: always
|
|
volumes:
|
|
- redis-data:/data
|
|
networks:
|
|
- app_network
|
|
ports:
|
|
- 6379:6379
|
|
|
|
electric:
|
|
container_name: electric
|
|
image: electricsql/electric:1.2.4@sha256:20da3d0b0e74926c5623392db67fd56698b9e374c4aeb6cb5cadeb8fea171c36
|
|
restart: always
|
|
environment:
|
|
DATABASE_URL: postgresql://postgres:postgres@database:5432/postgres?sslmode=disable
|
|
ELECTRIC_INSECURE: true
|
|
ELECTRIC_ENABLE_INTEGRATION_TESTING: true
|
|
networks:
|
|
- app_network
|
|
ports:
|
|
- "3060:3000"
|
|
depends_on:
|
|
- database
|
|
|
|
electric-shard-1:
|
|
container_name: electric-shard-1
|
|
image: electricsql/electric:1.2.4@sha256:20da3d0b0e74926c5623392db67fd56698b9e374c4aeb6cb5cadeb8fea171c36
|
|
restart: always
|
|
environment:
|
|
DATABASE_URL: postgresql://postgres:postgres@database:5432/postgres?sslmode=disable
|
|
ELECTRIC_INSECURE: true
|
|
ELECTRIC_REPLICATION_STREAM_ID: "triggershard1"
|
|
networks:
|
|
- app_network
|
|
ports:
|
|
- "3061:3000"
|
|
depends_on:
|
|
- database
|
|
|
|
clickhouse:
|
|
image: clickhouse/clickhouse-server:25.6.2
|
|
restart: always
|
|
container_name: clickhouse
|
|
ulimits:
|
|
nofile:
|
|
soft: 262144
|
|
hard: 262144
|
|
environment:
|
|
CLICKHOUSE_USER: default
|
|
CLICKHOUSE_PASSWORD: password
|
|
CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1
|
|
ports:
|
|
- "8123:8123"
|
|
- "9000:9000"
|
|
volumes:
|
|
- clickhouse-data:/var/lib/clickhouse
|
|
- clickhouse-logs:/var/log/clickhouse-server
|
|
networks:
|
|
- app_network
|
|
healthcheck:
|
|
test:
|
|
[
|
|
"CMD",
|
|
"clickhouse-client",
|
|
"--host",
|
|
"localhost",
|
|
"--port",
|
|
"9000",
|
|
"--user",
|
|
"default",
|
|
"--password",
|
|
"password",
|
|
"--query",
|
|
"SELECT 1",
|
|
]
|
|
interval: "3s"
|
|
timeout: "5s"
|
|
retries: "5"
|
|
start_period: "10s"
|
|
|
|
clickhouse_migrator:
|
|
build:
|
|
context: ../internal-packages/clickhouse
|
|
dockerfile: ./Dockerfile
|
|
depends_on:
|
|
clickhouse:
|
|
condition: service_healthy
|
|
networks:
|
|
- app_network
|
|
command: ["goose", "${GOOSE_COMMAND:-up}"]
|
|
|
|
ch-ui:
|
|
image: ghcr.io/caioricciuti/ch-ui:latest
|
|
restart: always
|
|
ports:
|
|
- "5521:5521"
|
|
environment:
|
|
VITE_CLICKHOUSE_URL: "http://localhost:8123"
|
|
VITE_CLICKHOUSE_USER: "default"
|
|
VITE_CLICKHOUSE_PASS: "password"
|
|
networks:
|
|
- app_network
|
|
|
|
s2:
|
|
image: ghcr.io/s2-streamstore/s2
|
|
command: ["lite", "--init-file", "/s2-spec.json"]
|
|
volumes:
|
|
- ./config/s2-spec.json:/s2-spec.json:ro
|
|
ports:
|
|
- "4566:80"
|
|
networks:
|
|
- app_network
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "wget -qO- http://localhost:80/v1/basins?limit=1 || exit 1"]
|
|
interval: 2s
|
|
timeout: 3s
|
|
retries: 5
|
|
start_period: 3s
|
|
|
|
toxiproxy:
|
|
container_name: toxiproxy
|
|
image: ghcr.io/shopify/toxiproxy:latest
|
|
restart: always
|
|
volumes:
|
|
- ./config/toxiproxy.json:/config/toxiproxy.json
|
|
ports:
|
|
- "30303:30303" # Proxied webapp port
|
|
- "8474:8474" # Toxiproxy API port
|
|
networks:
|
|
- app_network
|
|
command: ["-host", "0.0.0.0", "-config", "/config/toxiproxy.json"]
|
|
|
|
nginx-h2:
|
|
image: nginx:1.27
|
|
container_name: nginx-h2
|
|
restart: unless-stopped
|
|
ports:
|
|
- "8443:8443"
|
|
volumes:
|
|
- ./config/nginx.conf:/etc/nginx/nginx.conf:ro
|
|
- ./config/certs:/etc/nginx/certs:ro
|
|
|
|
# Observability stack for local development
|
|
otel-collector:
|
|
container_name: otel-collector
|
|
image: otel/opentelemetry-collector-contrib:0.96.0
|
|
restart: always
|
|
command: ["--config", "/etc/otel-collector-config.yaml"]
|
|
volumes:
|
|
- ./config/otel-collector-config.yaml:/etc/otel-collector-config.yaml:ro
|
|
ports:
|
|
- "4317:4317" # OTLP gRPC receiver
|
|
- "4318:4318" # OTLP HTTP receiver
|
|
- "8889:8889" # Prometheus exporter
|
|
networks:
|
|
- app_network
|
|
|
|
prometheus:
|
|
container_name: prometheus
|
|
image: prom/prometheus:v2.54.1
|
|
restart: always
|
|
volumes:
|
|
- ./config/prometheus.yml:/etc/prometheus/prometheus.yml:ro
|
|
- prometheus-data:/prometheus
|
|
ports:
|
|
- "9090:9090"
|
|
networks:
|
|
- app_network
|
|
command:
|
|
- "--config.file=/etc/prometheus/prometheus.yml"
|
|
- "--storage.tsdb.path=/prometheus"
|
|
- "--web.enable-lifecycle"
|
|
|
|
grafana:
|
|
container_name: grafana
|
|
image: grafana/grafana:11.3.0
|
|
restart: always
|
|
volumes:
|
|
- grafana-data:/var/lib/grafana
|
|
- ./config/grafana/provisioning:/etc/grafana/provisioning:ro
|
|
ports:
|
|
- "3001:3000"
|
|
environment:
|
|
GF_SECURITY_ADMIN_USER: admin
|
|
GF_SECURITY_ADMIN_PASSWORD: admin
|
|
GF_USERS_ALLOW_SIGN_UP: false
|
|
networks:
|
|
- app_network
|
|
depends_on:
|
|
- prometheus
|