sabbajohn/pulse-laravel
Laravel SDK for Pulse that offers a clean, framework-native integration for connecting your application to Pulse. Publish the config, set your credentials, and use simple Laravel helpers to get started with minimal boilerplate.
Prerequisites
sabbajohn/pulse-php must be ^0.1.5. Older pins will not satisfy the new provisioning code paths.Installing is a no-op (by design)
The release is opt-in. composer require/composer update runs no migration and issues no HTTP request. If you do nothing else, behaviour is identical to the previous version. That is the intended default — don't "helpfully" enable it in a shared config.
Where to look first, in order
config/*.php → the provisioning block and its enabled flag. Read it before anything else; nearly every "nothing happens" report traces back here.php artisan vendor:publish and pick the provisioning tag deliberately.First use case (local/staging only)
Publish the migration tag → php artisan migrate → bind the customer hook and credentials resolver → enable the flag in a non-production env → point at a stub/sandbox endpoint (the real backend isn't up) → dispatch a single provisioning job inside a transaction → inspect the encrypted intent/result rows and confirm the scanner picks up a deliberately killed job. That sequence validates the whole loop without touching a live partner API.
Gate everything through config, per environment
Enable provisioning only in the envs where the hook and resolver are actually bound. A missing hook plus an enabled flag is the most common self-inflicted outage in opt-in features like this.
Customer hook: keep it pure and deterministic
The hook decides what gets provisioned. It should read from already-persisted state, return the same answer on re-invocation, and perform no I/O. Because the package guarantees a stable key and payload across timeout and queue failures, any non-determinism in your hook (timestamps, random suffixes, now() in the payload) breaks that guarantee and produces duplicate or mismatched provisions.
Dispatch inside the transaction, let afterCommit do the work
The release uses afterCommit dispatch. Write the pattern as:
dispatch() in the same DB transactionafterCommit-disabled context — you'll get a job that runs before the row exists, and the fenced lease will then reject the writeCredentials resolver: authorize, then resolve
Bind the resolver behind your existing policy/authorization layer. The release calls out "authorized credentials resolver" — the resolver is where partner credentials enter the flow, so the check belongs at resolution time, not at dispatch time (dispatch can be minutes stale after a recovery scan).
Recovery scanner as a scheduled command
Register the scanner in routes/console.php / the scheduler with withoutOverlapping() and a run interval shorter than your acceptable recovery latency. The scanner is what makes timeouts and queue failures survivable — if it isn't scheduled, "durable" is a claim, not a property.
Testing the retry classifier
Use Http::fakeSequence() to assert both branches explicitly:
Retry-After must be retried and must honour the header valueAssert the persisted intent/result state, not just the HTTP calls — the value of this release is the durable record.
Reading results
Results are read via the primary connection by design ("primary reads prevent credential crossover"). Route any verification/readback code through the primary connection too, so your assertions match what the package sees.
Silent no-op is the default failure mode. Disabled by default + no auto-migration means "nothing happened" is usually correct behaviour. Check the flag before you debug anything.
Enabling without migrating. Because the publish step is an explicit tag, it's easy to flip the flag on an environment where the migration never ran. Symptom: missing-table errors only on the provisioning path. Add a deploy-time assertion that the tables exist when the flag is enabled.
The backend isn't deployed. Every real HTTP call in this release points at a draft PR. Stub or fake the endpoint; do not interpret connection failures as a package bug.
Terminal errors do not retry — even with junk bodies. A misconfigured reverse proxy returning an HTML 404/403 will terminate the provisioning attempt rather than retry. That's correct behaviour but it means auth/routing misconfig surfaces as a permanent failure, not a noisy retry loop. Alert on terminal states, don't wait for retries to reveal them.
Retry-After vs your queue's retry_after. If the server asks for a longer delay than the queue's retry_after window, the job can be released and re-reserved before the honour window elapses. The fenced lease prevents the corruption, but you'll see lease-rejection noise. Keep the queue retry_after comfortably above the largest Retry-After you expect.
Leases fence, they don't warn. A worker that overruns its lease is prevented from overwriting state — and the write is simply dropped. Keep provisioning jobs short; if your hook does heavy work, move that work upstream into the transaction phase.
Do not normalise credentials or identifiers. "Exact namespace digests and binary original comparison" means trimming, lowercasing, or whitespace-collapsing an identifier anywhere in your own code can make it mismatch what was stored. Pass values through untouched.
Diagnosing "wrong partner" symptoms. Suspect a replica read before suspecting a bug — stale replica data looks exactly like credential crossover, and the package's primary-read design exists to avoid that confusion.
Platform caveats are real, not boilerplate. MySQL and the extended Laravel runtime matrix are not validated in this release. Pin the PHP/Laravel/driver combination you actually tested, and keep MySQL out of the rollout plan until a validated release lands.
Extension points worth knowing: the customer hook, the credentials resolver, the migration publish tag, the scanner command, and the config gate. Those five cover virtually every customisation you'd want — reach for them before patching vendor code.
How can I help you explore Laravel packages today?