stem 0.1.0-alpha.3
stem: ^0.1.0-alpha.3 copied to clipboard
Stem is a Dart-native background job platform with Redis Streams, retries, scheduling, observability, and security tooling.
Stem #
Stem is a Dart-native background job platform. It gives you Celery-style task execution with a Dart-first API, Redis Streams integration, retries, scheduling, observability, and security tooling—all without leaving the Dart ecosystem.
Install #
dart pub add stem # core runtime APIs
dart pub add stem_redis # Redis broker + result backend
dart pub add stem_postgres # (optional) Postgres broker + backend
dart pub global activate stem_cli
Add the pub-cache bin directory to your PATH so the stem_cli tool is available:
export PATH="$HOME/.pub-cache/bin:$PATH"
stem --help
Quick Start #
import 'dart:async';
import 'package:stem/stem.dart';
import 'package:stem_redis/stem_redis.dart';
class HelloTask implements TaskHandler<void> {
@override
String get name => 'demo.hello';
@override
TaskOptions get options => const TaskOptions(
queue: 'default',
maxRetries: 3,
rateLimit: '10/s',
visibilityTimeout: Duration(seconds: 60),
);
@override
Future<void> call(TaskContext context, Map<String, Object?> args) async {
final who = args['name'] as String? ?? 'world';
print('Hello $who (attempt ${context.attempt})');
}
}
Future<void> main() async {
final registry = SimpleTaskRegistry()..register(HelloTask());
final broker = await RedisStreamsBroker.connect('redis://localhost:6379');
final backend = await RedisResultBackend.connect('redis://localhost:6379/1');
final stem = Stem(broker: broker, registry: registry, backend: backend);
final worker = Worker(broker: broker, registry: registry, backend: backend);
unawaited(worker.start());
await stem.enqueue('demo.hello', args: {'name': 'Stem'});
await Future<void>.delayed(const Duration(seconds: 1));
await worker.shutdown();
await broker.close();
await backend.close();
}
Features #
- Task pipeline – enqueue with delays, priorities, idempotency helpers, and retries.
- Workers – isolate pools with soft/hard time limits, autoscaling, and remote control (
stem worker ping|revoke|shutdown). - Scheduling – Beat-style scheduler with interval/cron/solar/clocked entries and drift tracking.
- Observability – Dartastic OpenTelemetry metrics/traces, heartbeats, CLI inspection (
stem observe,stem dlq). - Security – Payload signing (HMAC or Ed25519), TLS automation scripts, revocation persistence.
- Adapters – In-memory drivers included here; Redis Streams and Postgres adapters ship via the
stem_redisandstem_postgrespackages. - Specs & tooling – OpenSpec change workflow, quality gates (
tool/quality/run_quality_checks.sh), chaos/regression suites.
Documentation & Examples #
- Full docs: Full docs (run
npm install && npm startinside.site/). - Guided onboarding: Guided onboarding (install → infra → ops → production).
- Examples (each has its own README):
- rate_limit_delay – delayed enqueue, priority clamping, Redis rate limiter.
- dlq_sandbox – dead-letter inspection and replay via CLI.
- microservice, monolith_service, mixed_cluster – production-style topologies.
- security examples – payload signing + TLS profiles.
- postgres_tls – Redis broker + Postgres backend secured via the shared
STEM_TLS_*settings. - otel_metrics – OTLP collectors + Grafana dashboards.
Running Tests Locally #
Start the dockerised dependencies and export the integration variables before invoking the test suite:
source packages/stem_cli/_init_test_env
dart test
The helper script launches packages/stem_cli/docker/testing/docker-compose.yml
(Redis + Postgres) and populates STEM_TEST_* environment variables needed by
the integration suites.
Adapter Contract Tests #
Stem ships a reusable adapter contract suite in
packages/stem_adapter_tests. Adapter packages (Redis broker/postgres
backend, SQLite adapters, and any future integrations) add it as a
dev_dependency and invoke runBrokerContractTests /
runResultBackendContractTests from their integration tests. The harness
exercises core behaviours—enqueue/ack/nack, dead-letter replay, lease
extension, result persistence, group aggregation, and heartbeat storage—so
all adapters stay aligned with the broker and result backend contracts. See
test/integration/brokers/postgres_broker_integration_test.dart and
test/integration/backends/postgres_backend_integration_test.dart for
reference usage.