Download the PHP package gplanchat/durable-bridge-temporal without Composer
On this page you can find all versions of the php package gplanchat/durable-bridge-temporal. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download gplanchat/durable-bridge-temporal
More information about gplanchat/durable-bridge-temporal
Files in gplanchat/durable-bridge-temporal
Package durable-bridge-temporal
Short Description Temporal journal EventStore + worker (gRPC, no Temporal PHP SDK) for gplanchat/durable
License MIT
Informations about the package durable-bridge-temporal
gplanchat/durable-bridge-temporal (src/Bridge/Temporal)
gRPC bridge (without the official Temporal PHP SDK) to persist the Durable journal in a minimal Temporal workflow. The wire is ext-grpc by default; every collaborator depends on WorkflowServiceClientInterface, so the same RPCs also travel over curl, without the extension.
Read-only mirror. This repository is a subtree-split of gplanchat/durable-dev, published so Composer can require this package on its own. Issues and pull requests are disabled here — open them on the monorepo.
The tests are in the monorepo, not here. This split carries source only. What covers it is
tests/unit/Bridge/Temporal/in the monorepo, run by itsunitsuite.Documentation: durable.rocks.
PHP namespace: Gplanchat\Bridge\Temporal.
Deployment invariant: one Temporal server, one DSN, declared once in durable.temporal.dsn. The Durable bundle builds every worker from it — see Workers.
Requirements
- PHP ext-grpc, or ext-curl with HTTP/2 (used automatically when
ext-grpcis not loaded; also thetemporal+http://JSON gateway, client calls only) — see Withoutext-grpc - A reachable Temporal frontend (e.g.
host:7233)
Components
| Class | Role |
|---|---|
Store\TemporalReadThroughEventStore |
Implements Gplanchat\Durable\Store\EventStoreInterface: reads a run's history from the server when the local store has none; TemporalRuntimeAssembly::readThroughEventStore() builds it |
TemporalJournalTransport |
Symfony Messenger receive-only receiver: each get() long-polls a workflow task, replays the execution from the server's history and answers the task. The bundle registers it as durable_workflows |
TemporalActivityWorkerTransport |
Receive-only receiver: each get() long-polls an activity task, runs the handler and reports the outcome. The bundle registers it as durable_activities |
TemporalNexusWorkerTransport |
Receive-only receiver: each get() long-polls a Nexus task and serves the operation the application declared. The bundle registers it as durable_nexus once a handler exists |
GrpcWorkflowServiceClient |
The WorkflowService over gRPC; how each call travels is a GrpcTransport's |
GrpcTransport |
One gRPC unary call, for any service. ExtGrpcTransport (ext-grpc) is the bridge's; CurlGrpcTransport (ext-curl, HTTP/2) and GuzzleGrpcTransport (Guzzle 7.14+, cURL handler) come from gplanchat/grpc-client. WorkflowServiceClientFactory picks one from transport= |
TemporalBridgeBundle |
Deprecated, registers nothing: remove it from config/bundles.php |
Connection DSN
It goes once, in durable.temporal.dsn. Schemes: temporal:// (gRPC), temporal+tls:// (gRPC over TLS), temporal+http:// and temporal+https:// (the server JSON gateway, port 7243 by default). Query parameters: namespace, task_queue or journal_task_queue, workflow_task_queue, activity_task_queue, nexus_task_queue, identity, tls (bool, the older spelling of +tls), transport (auto by default: ext-grpc when loaded, curl otherwise; grpc, grpc-curl, guzzle, http to force one). Over TLS, ca, cert and key name PEM files (the CA that signs the server, and a client certificate for mTLS, cert and key together), and api_key is sent as authorization: Bearer … with the temporal-namespace header Temporal Cloud routes by. Any other key is refused, by name, and so is ca/cert/key/api_key without TLS. Over a PSR-18 client handed to the JSON gateway, TLS is that client's configuration: ca/cert/key are refused there.
Workers
One server, one DSN: the Durable bundle builds the workers from durable.temporal.dsn, and messenger:consume finds them by name. messenger.yaml declares no Temporal transport; if it declares one under a worker's name, the container refuses to compile and names it.
| Worker | Polls | Exists when |
|---|---|---|
durable_workflows |
workflow tasks | durable.temporal.dsn is set and durable.temporal.journal is not false |
durable_activities |
activity tasks | same |
durable_nexus |
Nexus tasks | durable.temporal.dsn is set and at least one Nexus handler is declared |
What Messenger's options do to these workers
The workers do their work inside get() and hand nothing to the Messenger worker (they use the
ReceiveOnlyTransport trait: nothing can be sent to them, nothing is acknowledged or rejected).
Everything Messenger ties to a handled message therefore never engages:
| Option | Effect on durable_workflows, durable_activities, durable_nexus |
|---|---|
retry_strategy, failure_transport (per transport) |
Cannot be set: declaring a transport under a worker's name fails the container build. Retries are the server's retry policy, and a failed poll is retried by the next get() |
framework.messenger.failure_transport (global) |
Applies to your other transports, never to these |
--limit, --failure-limit |
Ignored: no message is ever counted, so the worker never stops on them |
--time-limit, --memory-limit, SIGTERM |
Work as usual: use them to recycle a worker |
--sleep |
Applies after every task, since none counts as a handled message: the worker waits what is left of --sleep (1 s by default) once a task took less than that. The long poll already waits for work, so --sleep=0 removes that pause |
Without ext-grpc: curl, or the JSON gateway
The classes live under Gplanchat\Bridge\Temporal\Http and need ext-curl built with HTTP/2
(nghttp2), which every mainstream distribution ships.
| DSN | Class | Port | Covers |
|---|---|---|---|
temporal://, temporal+tls:// without ext-grpc (or transport=grpc-curl to force it) |
GrpcWorkflowServiceClient over CurlGrpcTransport (gplanchat/grpc-client) |
7233 (the gRPC frontend) | Every RPC the bridge uses, workers included. Same protocol as ext-grpc: one HTTP/2 POST per unary call, gRPC frame in the body, status in the trailers. |
temporal+http://, temporal+https:// |
JsonGatewayWorkflowServiceClient |
7243 (the JSON gateway) | The client side: start, signal, query, update, describe, list, history, cancel, terminate, and the activity completion RPCs. No task queue poll and no workflow or Nexus task response: the server does not bind them over HTTP. Calling one throws with gRPC code 12 (UNIMPLEMENTED). |
Both throw the same \RuntimeException as the ext-grpc path, with the gRPC status code as the
exception code, so nothing above the transport tells them apart. Which one a process ended up with
is printed by durable:execution:diagnose (Symfony) and by the worker commands (Laravel) at start.
Enabling the JSON gateway on a self-hosted server
The development server takes --http-port 7243. Temporal Cloud exposes the gateway on its own
endpoint; consult its documentation for the address.
The gateway over a PSR-18 client
The gateway is plain HTTP and JSON, so any PSR-18 client can carry it instead of curl. Hand one, with its PSR-17 factories, to the factory:
Symfony's Psr18Client serves as its own factory: new Psr18Http($psr18, $psr18, $psr18). PSR-18
has no per-request timeout: the deadline is the client's own configuration, and a timeout reports
as UNAVAILABLE like any other network failure.
Limits
- A proxy or load balancer that only speaks HTTP/1.1 breaks
grpc-curl, as it breaksext-grpc;httpsurvives it. - Protobuf encoding is the pure-PHP runtime: correct, and slower than the C extension on large
history pages. Install
ext-protobufif that shows up in a profile.
Symfony
- In the monorepo the code lives under
src/Bridge/Temporal; in a split repo:composer require gplanchat/durable-bridge-temporal. - Set
durable.temporal.dsnin the Durable bundle configuration. messenger:consume durable_workflows durable_activities, plusdurable_nexusif the application serves operations — see Workers.
FrankenPHP worker
Same idea as messenger:consume: run the Messenger worker under FrankenPHP worker mode (or systemd) with messenger:consume durable_workflows durable_activities.
License
MIT — see WA004.
Further reading
- DUR019 — Temporal gRPC bridge and journal:
documentation/adr/DUR019-temporal-grpc-bridge-and-journal.md
All versions of durable-bridge-temporal with dependencies
google/common-protos Version ^4.9
google/protobuf Version ^4.31
gplanchat/durable Version ^0.1.0-beta1
grpc/grpc Version ^1.57
php Version >=8.2
psr/log Version ^1.1 || ^2.0 || ^3.0
roadrunner-php/roadrunner-api-dto Version ^1.17
symfony/config Version ^6.4 || ^7.0 || ^8.0
symfony/dependency-injection Version ^6.4 || ^7.0 || ^8.0
symfony/http-kernel Version ^6.4 || ^7.0 || ^8.0
symfony/messenger Version ^6.4 || ^7.0 || ^8.0