wundii / flowcrafter
Requires
- php: >=8.2
- ramsey/uuid: ^4.9
- symfony/console: ^6.4 | ^7.0 | ^8.0
- symfony/http-foundation: ^6.4 | ^7.0 | ^8.0
- symfony/process: ^6.4 | ^7.0 | ^8.0
- symfony/routing: ^6.4 | ^7.0 | ^8.0
- wundii/data-mapper: ^1.4.12
Requires (Dev)
- ext-pdo: *
- ext-redis: *
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^11.5
- rector/rector: ^2.1
- symfony/var-dumper: ^6.4 | ^7.0 | ^8.0
- symplify/easy-coding-standard: ^12.5
- testcontainers/testcontainers: ^1.0.4
- thenativeweb/eventsourcingdb: ^1.4.0
- wundii/phplint: ^0.3
README
PHP-Bibliothek zur Definition, Ausführung und Überwachung nachrichtengetriebener Workflows (State Machines). Flows werden als typsichere PHP-Klassen definiert und über austauschbare Storage-Backends persistiert.
Features
- Typsichere Workflow-Definitionen via PHP-Interfaces
- Drei Storage-Backends: MySQL, Redis, EventSourceDB
- Synchrone Ausführung (
FlowRunner) und asynchrone Queue-Verarbeitung (FlowObserver) - Vollständiges Message- und Exception-Logging pro Flow-Instanz
- REST-API über den integrierten Flower-Micro-Router
- Symfony Console Commands für Init, Observer und Mermaid-Diagramme
- PHPStan Level 10, ECS Code Style, vollständige Integration-Tests mit Testcontainers
Installation
composer require wundii/flowcrafter
Konfiguration
Erstelle eine flowcrafter.php im Projektstamm:
<?php use Wundii\Flowcrafter\Config\FlowcrafterConfig; return static function (FlowcrafterConfig $config): void { $config->setStorageClass('Wundii\Flowcrafter\Storage\MySql'); $config->setStorageHost('localhost'); $config->setStoragePort(3306); $config->setStorageDatabase('flowcrafter'); $config->setStorageUsername('user'); $config->setStoragePassword('password'); $config->setServerSecret('bearer-token-secret'); $config->setServerDescription('Mein FlowCrafter Service'); };
Beispiele für alle Backends liegen unter flowcrafter-redis.php und flowcrafter-esdb.php.
Storage-Backends im Überblick
| Backend | Klasse | Besonderheit |
|---|---|---|
| MySQL | Storage\MySql |
Relationales Schema, Transaktionen, PDO |
| Redis | Storage\Redis |
In-Memory, RediSearch-Indizes |
| EventSourceDB | Storage\Esdb |
Event Sourcing, Append-Only |
Inbetriebnahme
1. Storage initialisieren
vendor/bin/flowcrafter init
Legt alle Tabellen / Indizes im konfigurierten Backend an.
2. API-Server + Observer starten
vendor/bin/flowcrafter serve
Startet den API-Server und den Observer zusammen in einem Kommando. Ctrl+C beendet beide Prozesse.
| Option | Default | Beschreibung |
|---|---|---|
--host |
0.0.0.0 |
Server-Host |
--port |
8000 |
Server-Port |
Alternativ einzeln starten:
# Nur API-Server php -S localhost:8000 service/index.php # Nur Observer vendor/bin/flowcrafter observer
Projektstruktur
flowcrafter/
├── src/
│ ├── Config/
│ │ └── FlowcrafterConfig.php # Konfigurationsklasse
│ ├── Console/Commands/
│ │ ├── FlowInitCommand.php # Storage initialisieren
│ │ ├── FlowCreateCommand.php # Flow registrieren
│ │ ├── FlowObserverCommand.php # Observer-Daemon starten
│ │ ├── FlowServeCommand.php # API-Server + Observer starten
│ │ └── FlowMermaidCommand.php # Mermaid-Diagramm erzeugen
│ ├── Interface/
│ │ ├── StorageInterface.php # Backend-Abstraktion
│ │ ├── FlowInterface.php # Flow-Implementierungsvertrag
│ │ ├── MessageInterface.php # Basistyp für alle Messages
│ │ ├── MessageInitInterface.php # Marker: Startnachricht
│ │ ├── MessageDataInterface.php # Marker: Datennachricht
│ │ ├── MessageReturnInterface.php # Marker: Rückgabewert (Flow-Ende)
│ │ └── StubInterface.php # Prozessoreinheit
│ ├── Storage/
│ │ ├── MySql.php # MySQL-Implementierung
│ │ ├── Redis.php # Redis-Implementierung
│ │ └── Esdb.php # EventStore DB-Implementierung
│ ├── Flow.php # Flow-Instanz (Domain Model)
│ ├── FlowSchema.php # Workflow-Definition (Blueprint)
│ ├── FlowRunner.php # Synchrone Ausführungs-Engine
│ ├── FlowObserver.php # Asynchroner Queue-Prozessor
│ ├── FlowMessage.php # Nachrichtenobjekt
│ ├── FlowException.php # Exception-Objekt mit Kontext
│ ├── FlowRun.php # Ausführungsprotokoll
│ └── Stub.php # Prozessor-Unit
├── service/
│ ├── Flower/ # Flower Micro-Router
│ │ ├── Flower.php # Singleton: Request-Handling, Auth
│ │ ├── Router.php # Routen-Registry (Symfony Routing)
│ │ └── MethodEnum.php # GET, POST, PUT, DELETE, …
│ └── index.php # API-Einstiegspunkt
├── tests/ # PHPUnit + Testcontainers
└── composer.json
Konzepte
Flow
Ein Flow ist eine Workflow-Instanz, identifiziert durch einen flowHash (MD5 des Schemas) und einen flowRuntimeHash (UUIDv7 je Ausführung). Pro Flow werden alle Messages, Exceptions und Runs persistiert.
FlowSchema
Das Schema definiert den Workflow-Aufbau: welche StubInterface-Implementierungen existieren, welche Nachrichtentypen sie konsumieren und welcher Message-Typ den Flow initialisiert bzw. abschließt.
Messages & State Transitions
| Zustand | Bedeutung |
|---|---|
WAIT |
Message wartet auf weitere Inputs im Stub |
PROCESS |
Alle Inputs vorhanden, Stub wird ausgeführt |
FINISH |
Message wurde verarbeitet |
Ein Stub kann zurückgeben:
MessageInterface→ Flow läuft weiterMessageReturnInterface→ Flow endetfalse→ Keine Aktion
Observer (asynchrone Verarbeitung)
appendObserveItem() legt eine Message in die Queue. Der FlowObserver-Daemon pollt observeQueue(), deserialisiert die Messages und führt sie via FlowRunner aus. Exceptions werden protokolliert, der Observer läuft mit 2s Retry-Delay weiter.
API-Endpunkte
Die REST-API wird über service/index.php bereitgestellt (Flower Micro-Router). Alle Endpunkte außer GET / und GET /metrics erfordern einen Bearer-Token (setServerSecret()).
Flows & Exceptions
| Methode | Pfad | Parameter | Beschreibung |
|---|---|---|---|
| GET | /api/ping |
— | Verbindungstest (pong) |
| GET | /api/info |
— | Server-Info + Observer-Status |
| GET | /api/flows |
sort, top, source |
Alle Flow-Instanzen |
| GET | /api/flows/detail |
hash oder runtimeHash |
Flow mit Messages & Exceptions |
| GET | /api/exceptions |
sort, top, flowHash |
Alle Exceptions |
Ausführung & Queue
| Methode | Pfad | Body | Beschreibung |
|---|---|---|---|
| POST | /api/flows/run |
{ flowHash, messageSource, message } |
Flow synchron ausführen |
| POST | /api/queue |
{ flowHash, messageSource, message } |
Flow in die Queue stellen |
| GET | /api/queue/count |
— | Aktuelle Queue-Größe |
Monitoring
| Methode | Pfad | Auth | Beschreibung |
|---|---|---|---|
| GET | /metrics |
keine | Prometheus / OpenMetrics Exposition |
Monitoring (Prometheus / OpenMetrics)
Der Endpunkt GET /metrics gibt Metriken im Prometheus-Textformat (Version 0.0.4) zurück und ist ohne Authentication erreichbar. Die Absicherung erfolgt auf Netzwerkebene (Firewall, Reverse Proxy).
Exportierte Metriken:
| Metrik | Typ | Beschreibung |
|---|---|---|
flowcrafter_info |
gauge | Immer 1, Label description enthält die Server-Beschreibung |
flowcrafter_observer_up |
gauge | 1 = Observer läuft, 0 = Observer gestoppt |
flowcrafter_queue_size |
gauge | Aktuelle Anzahl der Einträge in der Queue |
Beispielausgabe:
# HELP flowcrafter_info FlowCrafter service information
# TYPE flowcrafter_info gauge
flowcrafter_info{description="Production"} 1
# HELP flowcrafter_observer_up Whether the FlowCrafter observer process is running (1 = up, 0 = down)
# TYPE flowcrafter_observer_up gauge
flowcrafter_observer_up 1
# HELP flowcrafter_queue_size Number of items currently pending in the queue
# TYPE flowcrafter_queue_size gauge
flowcrafter_queue_size 0
Prometheus-Konfiguration
scrape_configs: - job_name: flowcrafter static_configs: - targets: ['localhost:8000'] metrics_path: /metrics
CheckMK
In CheckMK den Prometheus Special Agent oder einen HTTP-Check auf /metrics einrichten. Das Format wird nativ als Prometheus-Exposition erkannt.
Console Commands
# Storage-Tabellen / -Indizes anlegen vendor/bin/flowcrafter init # Flow-Schema registrieren vendor/bin/flowcrafter create App\\MyFlow # API-Server + Observer zusammen starten vendor/bin/flowcrafter serve # Observer-Daemon einzeln starten vendor/bin/flowcrafter observer # Mermaid-Diagramm für einen Flow generieren vendor/bin/flowcrafter mermaid App\\MyFlow
Entwicklung
# Abhängigkeiten installieren composer install # Statische Analyse (PHPStan Level 10) + Code Style prüfen composer analyze # Code Style automatisch korrigieren composer format # Tests ausführen (benötigt Docker für Testcontainers) composer test # Analyse + Tests zusammen composer qa