Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
93c2f80
docs: propose universal message queue API with usage examples
dermatthes Sep 12, 2026
31824c5
docs: add compact request-reply API and metadata middleware examples
dermatthes Sep 12, 2026
b567dc8
docs: demonstrate broadcast lock coordination and competing RPC workers
dermatthes Sep 12, 2026
2af5e56
docs: design standard readiness checks and listener diagnostics
dermatthes Sep 12, 2026
8449ef9
docs: introduce PhoreMQ constructor alongside connection factory
dermatthes Sep 12, 2026
41fa5b9
docs: infer subscription metadata from typed callbacks and reject con…
dermatthes Sep 12, 2026
04e7285
docs: unify publish with optional await and direct runtime options
dermatthes Sep 12, 2026
93917ba
docs: explain worker limits and await timeout exceptions in examples
dermatthes Sep 12, 2026
2afbd99
docs: explain queue guarantees and simplify API error examples
dermatthes Sep 12, 2026
39acc80
docs: focus architecture on RabbitMQ and add local deployment setup
dermatthes Sep 12, 2026
a76d645
build: require PHP 8.5 and replace Python setup with PHP
dermatthes Sep 12, 2026
e1a1e99
docs: let publishers report missing queue configuration
dermatthes Sep 12, 2026
57ac673
docs: define queue profiles and RPC lifecycle across container restarts
dermatthes Sep 12, 2026
080a871
docs: add internal RabbitMQ Compose and anonymous authentication how-to
dermatthes Sep 12, 2026
59510b6
docs: configure RabbitMQ authentication directly in Compose
dermatthes Sep 12, 2026
ea96caf
docs: review MQ API around explicit application workflows and shared …
dermatthes Sep 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 75 additions & 5 deletions .ai-usage-info.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,83 @@

## Sinn der Library

[hier einfügen]
PhoreMQ ist der Entwurf einer frameworkunabhängigen PHP-Library für **RabbitMQ**.
Die erste Umsetzung enthält genau einen `RabbitMQConnector` hinter
`ConnectorInterface`. Es gibt keine Adapterregistrierung, Brokerauswahl oder
Fallback-Logik. Öffentliche Konfiguration verwendet die generischen Begriffe
Namespace, Topic, Subscription und Nachrichtentyp.

## Beispiele
**Status: Die PHP-API ist noch nicht implementiert.** Composer-Metadaten und
Autoloading stammen aus der Projektvorlage; PHP >=8.5 ist verbindlich. Docker Compose und das PHP-
Setup sind unabhängig von der geplanten PHP-Library verwendbar.

[hier beispiele in ./examples/ verlinken]
Vorgeschlagener Namespace: `Phore\MessageQueue`; keine implementierten
öffentlichen Klassen oder globalen Funktionen vorhanden. Der RabbitMQ-Adapter
verwendet AMQP 0-9-1, Quorum Queues, Publisher Confirms und Ack nach Handler-Erfolg.
Topologie-Abbildung und Grenzen sind im Proposal §§ 2–7 festgelegt.

## Globale Funktionen
Das zentrale Objekt wird einmal pro Prozess mit DSN oder Adapter und
`ConnectionOptions` erzeugt. `ConnectionFactory` bleibt ein einfacher
Konstruktor-Helfer. Alle Beispiele laden dieselbe Konfiguration über
`new PhoreMQ(...demoConnection())`; konkrete Verbindungsoptionen stehen in Beispiel 01.

[hier links auf beispiele von speziellen funktionen einfügen]
`publish($dto)` oder `publish($topic, $type, $payload)` sendet sofort.
`subscribe` registriert Events, `respond` Commands, `run` verarbeitet
Zustellungen. `publish(...)->await(timeoutSeconds: 5)` wartet optional auf eine
Antwort und wirft bei Ablauf `RequestTimeoutException`. `await` sendet nichts
noch einmal. Eigene freigegebene Remote-Exceptions sind möglich.

`subscribe($callback)` und `#[Subscribe]` übernehmen die Metadaten des ersten
DTO-Parameters; widersprüchliche Angaben werden früh abgelehnt. Optional prüft
und hydriert `phore/schema` die lokale Struktur. Sender und Empfänger müssen
nicht dieselbe PHP-Klasse verwenden. Metadaten, HMAC-Signierung, Middleware und
verifizierte Dateireferenzen bleiben außerhalb der fachlichen Payload.

**An alle:** eigene Subscription pro Empfänger. **An einen:** mehrere Worker
verwenden dieselbe Subscription. RabbitMQ verteilt Zustellungen; wiederholte
Verarbeitung bleibt möglich und benötigt fachliche Idempotenz.
`check()` prüft Verbindung und nachrichtenspezifische Bereitschaft. `HealthState`
meldet Dienstprobleme und Wiederherstellung im gemeinsamen Statusformat.
Ein Broker-Ping allein beweist keinen bereiten Handler.

## Beispiele und Setup

- [Architekturentscheidung und API-Proposal](docs/proposals/2026-09-12-message-queue-api.md)
- [Installation, Docker-Start und dynamische Topologie](docs/setup.md)
- [Gemeinsame Konfiguration](config/message-queue.json)
- [Message Queue Basics 101](docs/message-queue-basics-101.md)
- [Verbindung und zentrale Konfiguration](examples/api-draft/01-connect.php)
- [Programmatisch senden und empfangen](examples/api-draft/02-programmatic.php)
- [SDK-Typen und Handler mit Attributen](examples/api-draft/03-attributes.php)
- [ZIP-Dateien per verifizierter Speicherreferenz](examples/api-draft/04-files-and-local.php)
- [RPC mit Ergebnissen, Warnings und Remote-Exceptions](examples/api-draft/05-rpc.php)
- [Metadaten und Middleware](examples/api-draft/06-metadata-middleware.php)
- [Broadcast und Antworten aller erwarteten Teilnehmer](examples/api-draft/07-broadcast-locking.php)
- [Processing-Queue: ein Worker und ein Ergebnis](examples/api-draft/08-processing-workers.php)
- [Systemcheck und Dienststatus](examples/api-draft/09-system-check.php)
- [Callback-Fehler, Retry und Fehlerablage](examples/api-draft/10-callback-errors.php)

Projektregel: Ausführbare Beispiele und Setup-Skripte werden ausschließlich in PHP >=8.5 gepflegt; siehe [AGENTS.md](AGENTS.md).

`autoCreate` gilt für fachliche Topologie nur beim Registrieren von Listenern
(`subscribe`/`respond`). `publish`/`request` legen keine fachlichen Ressourcen an
und werfen bei fehlendem Topic oder nicht routbarer Nachricht direkt
`QueueConfigurationMissingException` (`TOPIC_MISSING` / `NO_MATCHING_SUBSCRIPTION`).
Vorhandene Queues ohne aktive Worker dürfen Backlog sammeln; für Bereitschaft
bleibt `check()` zuständig. RPC-Rückkanäle sind eine getrennte interne Einrichtung.

- [QueueOptions: Profile, Defaults, DTO-Attribute und Konflikte](examples/api-draft/11-queue-options.php)

RPC-Beispiel 05 beschreibt getrennte Docker-Publisher/Worker, private Rückkanäle,
automatisches Entfernen nach Connection-Ende, Request-Zuordnung und persistente
Idempotenz bei Neustarts. QueueOptions ersetzen separate retryPolicy-Vorgaben;
Work/RPC verwenden standardmäßig vier Versuche mit jeweils zehn Sekunden Abstand.
Bestehende Queue-Contracts werden geprüft und bei Konflikt abgelehnt, nicht
zwischen Container-Versionen automatisch hin- und hergeschrieben. Alles bleibt
API-Entwurf; keine MQ-Runtime ist durch diese Beispiele implementiert.

[Internes Docker-Deployment ohne Management-Plugin, optional SASL ANONYMOUS](deployment/rabbitmq/HOWTO.md): Compose-Netzwerk und Datenvolume werden automatisch angelegt; das How-to erklärt vHost, Ports und die noch fehlende Kompatibilität mit der vollständigen PhoreMQ-Topologieprüfung.

Die internen Compose-Beispiele konfigurieren die Anmeldung direkt über `RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS` im offiziellen Image; zusätzliche `.conf`-Dateien sind nicht erforderlich.

[Anwendungsbeispiele mit Ablauf- und Objektübersicht](examples/api-draft/README.md): Sender/Worker getrennt, RPC über `request($dto)->await()`, Sendekonfiguration einheitlich in `PublishOptions`. Antwortfrist: `replyTimeoutSeconds` beim Versand; lokales Warten: `timeoutSeconds` bei `await`.
7 changes: 7 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Projektregeln für phore/message-queue

- Mindestversion ist PHP 8.5 (`>=8.5`), für Library-Code, Tests, Beispiele und ausführbare Setup-/Hilfsskripte. Keine Kompatibilitätsschichten für ältere PHP-Versionen vorsehen.
- Ausführbare Beispiele und Setup-/Hilfsskripte werden ausschließlich in PHP geschrieben. Dokumentationsbeispiele verwenden ebenfalls PHP. Deklarative JSON-/YAML-Konfiguration und Shell-Befehle zum Aufrufen von PHP, Composer und Docker bleiben zulässig.
- Zunächst wird ausschließlich RabbitMQ über einen Adapter hinter `ConnectorInterface` umgesetzt. Keine Adapterregistrierung, Brokerauswahl oder Fallback-Logik; öffentliche Begriffe bleiben Namespace, Topic, Subscription und Nachrichtentyp.
- `docs/setup.md`, `examples/` und die Deployment-Dateien werden gemeinsam mit den zugehörigen Änderungen im Repository gepflegt. Noch nicht implementierte PHP-APIs sind ausdrücklich als Entwurf zu kennzeichnen.
- Maßgeblicher Architekturentwurf: `docs/proposals/2026-09-12-message-queue-api.md`. Die Projektübersicht für Agenten steht in `.ai-usage-info.md`.
75 changes: 73 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,64 @@
# phore-project-template
Template Repository for phore library projects
# Phore Message Queue

PhoreMQ ist der Entwurf einer frameworkunabhängigen PHP-Library für **RabbitMQ**.
Die erste Umsetzung enthält genau einen `RabbitMQConnector` hinter
`ConnectorInterface`. Es gibt keine Adapterregistrierung, Brokerauswahl oder
Fallback-Logik. Öffentliche Konfiguration verwendet die generischen Begriffe
Namespace, Topic, Subscription und Nachrichtentyp.

**Status: Die PHP-API ist noch nicht implementiert.** Composer-Metadaten und
Autoloading stammen aus der Projektvorlage; PHP >=8.5 ist verbindlich. Docker Compose und das PHP-
Setup sind unabhängig von der geplanten PHP-Library verwendbar.

Vom Repository-Verzeichnis aus:

```bash
docker compose -f deployment/rabbitmq/compose.yaml up -d --wait
php deployment/rabbitmq/setup.php
```

AMQP: `amqp://demo:demo@127.0.0.1:5672/demo`; Management:
`http://127.0.0.1:15672` mit `demo` / `demo`. Nur lokale Entwicklung.
Die PHP-Beispiele sind weiterhin API-Entwürfe.

- [Architekturentscheidung und API-Proposal](docs/proposals/2026-09-12-message-queue-api.md)
- [Installation, Docker-Start und dynamische Topologie](docs/setup.md)
- [Gemeinsame Konfiguration](config/message-queue.json)
- [Message Queue Basics 101](docs/message-queue-basics-101.md)
- [Verbindung und zentrale Konfiguration](examples/api-draft/01-connect.php)
- [Programmatisch senden und empfangen](examples/api-draft/02-programmatic.php)
- [SDK-Typen und Handler mit Attributen](examples/api-draft/03-attributes.php)
- [ZIP-Dateien per verifizierter Speicherreferenz](examples/api-draft/04-files-and-local.php)
- [RPC mit Ergebnissen, Warnings und Remote-Exceptions](examples/api-draft/05-rpc.php)
- [Metadaten und Middleware](examples/api-draft/06-metadata-middleware.php)
- [Broadcast und Antworten aller erwarteten Teilnehmer](examples/api-draft/07-broadcast-locking.php)
- [Processing-Queue: ein Worker und ein Ergebnis](examples/api-draft/08-processing-workers.php)
- [Systemcheck und Dienststatus](examples/api-draft/09-system-check.php)
- [Callback-Fehler, Retry und Fehlerablage](examples/api-draft/10-callback-errors.php)

Das zentrale Objekt wird einmal pro Prozess mit DSN oder Adapter und
`ConnectionOptions` erzeugt. `ConnectionFactory` bleibt ein einfacher
Konstruktor-Helfer. Alle Beispiele laden dieselbe Konfiguration über
`new PhoreMQ(...demoConnection())`; konkrete Verbindungsoptionen stehen in Beispiel 01.

`publish($dto)` oder `publish($topic, $type, $payload)` sendet sofort.
`subscribe` registriert Events, `respond` Commands, `run` verarbeitet
Zustellungen. `publish(...)->await(timeoutSeconds: 5)` wartet optional auf eine
Antwort und wirft bei Ablauf `RequestTimeoutException`. `await` sendet nichts
noch einmal. Eigene freigegebene Remote-Exceptions sind möglich.

`subscribe($callback)` und `#[Subscribe]` übernehmen die Metadaten des ersten
DTO-Parameters; widersprüchliche Angaben werden früh abgelehnt. Optional prüft
und hydriert `phore/schema` die lokale Struktur. Sender und Empfänger müssen
nicht dieselbe PHP-Klasse verwenden. Metadaten, HMAC-Signierung, Middleware und
verifizierte Dateireferenzen bleiben außerhalb der fachlichen Payload.

**An alle:** eigene Subscription pro Empfänger. **An einen:** mehrere Worker
verwenden dieselbe Subscription. RabbitMQ verteilt Zustellungen; wiederholte
Verarbeitung bleibt möglich und benötigt fachliche Idempotenz.
`check()` prüft Verbindung und nachrichtenspezifische Bereitschaft. `HealthState`
meldet Dienstprobleme und Wiederherstellung im gemeinsamen Statusformat.
Ein Broker-Ping allein beweist keinen bereiten Handler.

## Git Submodules

Expand All @@ -16,4 +75,16 @@ git submodule update --init --recursive
git submodule update --remote --merge
```

Projektregel: Ausführbare Beispiele und Setup-Skripte werden ausschließlich in PHP >=8.5 gepflegt; siehe [AGENTS.md](AGENTS.md).

- [QueueOptions: Profile, Defaults, DTO-Attribute und Konflikte](examples/api-draft/11-queue-options.php)

RPC-Beispiel 05 beschreibt getrennte Docker-Publisher/Worker, private Rückkanäle,
automatisches Entfernen nach Connection-Ende, Request-Zuordnung und persistente
Idempotenz bei Neustarts. QueueOptions ersetzen separate retryPolicy-Vorgaben;
Work/RPC verwenden standardmäßig vier Versuche mit jeweils zehn Sekunden Abstand.
Bestehende Queue-Contracts werden geprüft und bei Konflikt abgelehnt, nicht
zwischen Container-Versionen automatisch hin- und hergeschrieben. Alles bleibt
API-Entwurf; keine MQ-Runtime ist durch diese Beispiele implementiert.

[Anwendungsbeispiele mit Ablauf- und Objektübersicht](examples/api-draft/README.md): Sender/Worker getrennt, RPC über `request($dto)->await()`, Sendekonfiguration einheitlich in `PublishOptions`. Antwortfrist: `replyTimeoutSeconds` beim Versand; lokales Warten: `timeoutSeconds` bei `await`.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
]
},
"require": {
"php" : ">=8.3",
"php" : ">=8.5",
"ext-yaml": "*",
"ext-json": "*"
},
Expand Down
36 changes: 36 additions & 0 deletions config/message-queue.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"connection": "amqp://demo:demo@127.0.0.1:5672/demo",
"options": {
"autoCreate": true,
"maxInFlight": 1,
"security": {
"mode": "unsigned"
},
"rpc": {
"enabled": true,
"replyNamespace": "_phore.rpc"
},
"managementUrl": "http://127.0.0.1:15672"
},
"topics": [
"users",
"telemetry"
],
"subscriptions": [
{
"topic": "users",
"name": "audit-users",
"type": "user.created.v1"
},
{
"topic": "users",
"name": "billing-users",
"type": "user.created.v1"
},
{
"topic": "telemetry",
"name": "audit-telemetry",
"type": null
}
]
}
Loading
Loading