Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Gps Messenger Bundle Laravel Package

petitpress/gps-messenger-bundle

Google Pub/Sub transport for Symfony Messenger with zero extra dependencies beyond core Symfony and Pub/Sub libraries. Supports DSN and options config, automatic topic/subscription creation, message ordering via OrderingKeyStamp, dead letter policies, and keep-alive for long-running workers.

View on GitHub
Deep Wiki
Context7

Getting Started

First, calibrate your expectations: this is a Symfony bundle, not a Laravel package. There is no ServiceProvider, no config/gps-messenger.php, and no php artisan command that will publish anything useful. If you composer require petitpress/gps-messenger-bundle in a Laravel app, all you'll get is an unused Bundle class and a hard dependency tree of symfony/* packages that will not boot without a Symfony kernel.

So the realistic "day-one" paths for a Laravel developer are:

  1. Read it as a reference implementation of a Google Pub/Sub transport for a message bus. This is the highest-value use of the package: Transport\PubSubTransport, Transport\PubSubReceiver, Transport\PubSubSender, and the TransportFactory show the exact shape of a Pub/Sub driver (DSN parsing, subscribe/publish, message ack/nack, envelope handling). You will port those ideas to a Laravel Queue\Connector + Queue\Job pair.
  2. Consume it from a Symfony sidecar service if your organisation runs Symfony microservices next to Laravel apps. Laravel dispatches via a small HTTP/gRPC call or a shared Pub/Sub topic; the Symfony worker uses this bundle.
  3. Standalone symfony/messenger inside a Laravel Artisan command (advanced, fragile): composer require symfony/messenger symfony/serializer petitpress/gps-messenger-bundle google/cloud-pubsub, then manually wire the transport factory in a service container you construct yourself inside an Artisan\Command. Only do this if you truly must run the Symfony transport in-process.

What to look at first (in order):

  • composer.json — confirm symfony/messenger and google/cloud-pubsub versions and PHP constraint (PHP 8.1+).
  • DependencyInjection/ and Resources/config/ — how the transport factory is registered and how the DSN is parsed (gps://project/topic?keyFile=...).
  • Transport/ — the wire-level send/receive logic; this is what you'd reimplement for Laravel.
  • README for the DSN grammar (project, topic, subscription, options like auto_setup).

First concrete use case (port the pattern): Create a Laravel queue connection that mirrors the DSN, wrap google/cloud-pubsub PubSubClient, publish an envelope-encoded payload from dispatch(), and acknowledge messages in a queue:work loop. The bundle shows you the exact client calls (publish(), pull(), acknowledge()) and payload envelope shape to use.

Implementation Patterns

Pattern 1 — Symfony sidecar + Laravel producer (most pragmatic). Laravel publishes a normal JSON payload to Pub/Sub (using google/cloud-pubsub directly, or a Job dispatched to a thin adapter). The Symfony service, running this bundle, consumes the topic with messenger:consume. Laravel never imports the bundle. You get the battle-tested receiver/retry behaviour on the consumer side without fighting the framework gap.

Pattern 2 — Steal the transport, keep Laravel's bus. Build a GooglePubSubConnector implementing Illuminate\Contracts\Queue\Queue and a GooglePubSubJob implementing Illuminate\Contracts\Queue\Job. Mirror the bundle's PubSubSender::send() envelope (Symfony's Envelope → array with body, headers) so a Symfony worker and a Laravel worker can interoperate on the same topic. Use Laravel's Illuminate\Queue\Queue::enqueueUsing() for the standard before/after job hooks so failed jobs, retry_after, and events keep working. Key methods to copy semantics from: PubSubReceiver::get(), PubSubReceiver::ack(), PubSubReceiver::reject() — map reject to ack (Pub/Sub has no nack-with-requeue like RabbitMQ; a nacked message simply returns to the subscription).

Pattern 3 — DSN-driven transport config. Follow the bundle's DSN convention so ops teams see one grammar across services: gps://{projectId}/{topic}?subscription={sub}&keyFile={path}. Parse via parse_url(), hydrate a config object. This makes .env files portable between Symfony and Laravel deployments.

Pattern 4 — Envelope/middleware parity. Symfony Messenger envelopes carry MessageBus stamps (Retry, Delay, DelayStamp). Laravel jobs carry tries, backoff, delay. On publish, translate Laravel's delay into a Pub/Sub attribute + client-side sleep before publish, or better, use a Cloud Scheduler / delayed-topic emulation, since native Pub/Sub has no delay. Persist tries/backoff as message attributes; on consume, read them into job properties so Illuminate\Queue\Worker (if you wire it that way) behaves consistently.

Pattern 5 — Worker loop. The bundle's receiver does a streaming pull. In Laravel, implement pop() to run a single pull with maxMessages + returnImmediately matching your worker's sleep. Run php artisan queue:work --queue=google-pubsub and let Laravel's worker handle backoff between empty pulls.

Gotchas and Tips

  • It is not a Laravel package — do not try to make it one. There is no getFacadeAccessor, no auto-discovery, no publishable config. Any tutorial that suggests adding it to config/app.php providers is misleading. Composer autoloading will happily load the classes, but nothing boots.
  • Credential resolution differs. Symfony's bundle typically reads keyFile from the DSN or a config path. google/cloud-pubsub also honours GOOGLE_APPLICATION_CREDENTIALS and workload identity. In Laravel, standardise on the env var to keep parity with GCP's own SDK and avoid passing a path through DSNs into logs.
  • Emulator is your friend for tests. The Pub/Sub emulator (PUBSUB_EMULATOR_HOST) works with google/cloud-pubsub regardless of Symfony/Laravel. Set it in phpunit.xml and skip this bundle entirely in test environments.
  • Pub/Sub is at-least-once. This bundle (and any port of it) does not give you exactly-once. Handlers must be idempotent. The Symfony Retry middleware pattern is worth copying into a Laravel Middleware that wraps handlers with a dedupe key.
  • No native delay, no native dead-letter. Dead-letter is a subscription-level attribute (set in GCP console / IaC), not something the bundle magically adds. Symfony's FailedMessageTransport needs a separate transport configured — Laravel's failed_jobs table has no direct equivalent; you either write to a second topic or a database.
  • Message size limit is 10 MB (Pub/Sub), Symfony's envelope overhead is small but real. Don't shove large Eloquent payloads — serialise IDs and refetch.
  • Ack semantics on failure. In PubSubReceiver, a thrown exception causes the message to be left un-acked (redelivered after ack deadline). In a Laravel port, make sure Job::delete() calls acknowledge() and Job::release() uses modifyAckDeadline() — the naive ->ack() everywhere will silently lose messages.
  • DSN parsing is fragile. The bundle's DSN accepts a keyFile query param that may be URL-encoded (paths with spaces break it). If you copy the parsing, urldecode() before realpath(), and validate that the file exists at boot, not at publish time.
  • Observability is on you. The bundle does little beyond logging. Add OpenTelemetry / Cloud Trace spans in your connector's push/pop. Log the Pub/Sub messageId into your Laravel context so php artisan queue:failed rows can be correlated with Cloud Logging.
  • Version pinning. Symfony Messenger and google/cloud-pubsub both move fast; pin both in composer.json even in a ported implementation, because transport interface changes (TransportInterface::send return type, PubSubClient constructor args) will break your fork silently.
  • Extension points (if you ever go Symfony). The TransportFactory is tagged via messenger.transport_factory; the receiver/sender are plain services you can decorate. In a Laravel port, expose the same seam: a ConnectorInterface resolved from the driver name in config/queue.php, so future backends (SQS, Redis) are swap-in.
  • 30 stars, one maintainer, no CI visible. Treat the bundle as a specification of intent, not a library you build a platform on. Read it, understand it, and either sidecar it or reimplement ~300 lines in your own app/Queue/GooglePubSub/ namespace so you control upgrade risk.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings