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

Webservice Core Async Bundle Laravel Package

hengebytes/webservice-core-async-bundle

Adds asynchronous web service request handling to Hengebytes WebService Core. It lets PHP applications dispatch concurrent calls without blocking, helping integrate slow or multiple remote services more efficiently while keeping core client workflows intact.

View on GitHub
Deep Wiki
Context7

Getting Started

This package serializes concurrent requests that share a cache entry: the first request does the expensive work (e.g. a slow SOAP/HTTP call), and any request that hits the lock waits, then reloads the now-populated response instead of repeating the call. v1.3.11 is primarily a correctness release for that wait-and-reload path, so if you are adopting it fresh, you are starting from the first version where the reload is trustworthy.

Minimal steps:

  1. Install and register the response modifiers (LockResponseLoaderResponseModifier, ReloadLockedResponseResponseModifier) in your request pipeline. Both rely on the container autowiring the MonologLogHandler; it resolves to null when logging is disabled, so you do not need to guard for that case.
  2. Publish/confirm your config and set logs/lock_wait_threshold (default 5s). This is the only knob the release adds, and it controls when lock contention becomes visible.
  3. Verify the ordering: log middleware, store-to-cache middleware, and unlock middleware must all sit on the reloaded response's pipeline. That ordering is exactly what was broken before this release.

First use case: wrap a single expensive upstream call behind a cache lock keyed by request identity, and confirm that a second concurrent request returns the first request's payload rather than a 423 placeholder.

Where to look first: CacheManager::awaitUnlock() (now returns the seconds waited as a float) is the cleanest instrumentation point, and ReloadLockedResponseResponseModifier::reloadLockedResponse() is the new public static entry point if you need to drive the reload yourself.

Implementation Patterns

Cache-lock scoping. Key the lock to the exact upstream call identity (URL + normalized body/params). Over-broad keys serialize unrelated traffic; over-narrow keys collapse nothing and you pay the lock cost for zero benefit.

Instrument the wait. awaitUnlock() returning a float lets you emit a metric or span attribute per wait without parsing logs. Prefer this for dashboards and reserve the log warning for alerting.

Customize the action name. Lock waits are logged as <customAction>:lock_wait. Set a per-endpoint action so a grep tells you which upstream is contended, not just that something waited.

Treat 423 as an internal signal. The placeholder (423 {"cacheId": ...}) is never returned to the caller as a successful response in this version. If your error mapping sees a 423 with a cacheId body from anywhere else (older node, proxy), map it to a retry, never to a user-facing success.

Surface real failures. Errors from the reloaded request now propagate with their original cause. Wrap the pipeline call in a try/catch and translate to your API's error shape — you will now get the actual exception rather than a swallowed transport error, so your existing catch blocks may start matching more than they used to.

Rely on lock release for retries. A failure in store-to-cache (TTL callback, tag assignment) or any Throwable before a response exists releases the lock immediately. That makes "fail fast, retry" safe: you will not sit behind a 60s TTL.

Custom pipeline. If you are building your own middleware stack (as soap-core-async-bundle v2.0.1 does), call ReloadLockedResponseResponseModifier::reloadLockedResponse() so the reloaded response goes through its own pipeline rather than being consumed as a raw response.

Gotchas and Tips

  • The lock TTL is 60s. A holder that dies mid-request blocks waiters for the full minute. Keep lock-scoped handlers fast and idempotent, and never do unbounded work inside the lock.
  • Upgrade if you saw "one request per minute". The pre-1.3.11 bug meant a waiter took only the raw response of the reloaded request, so the lock was never released and each subsequent waiter queued behind the TTL. The symptom is exactly one request per lock TTL succeeding — a telltale sign you are on an older version.
  • awaitUnlock() changed from void to float. Ignoring the return value is fine. Subclassing CacheManager or implementing an interface that declares void is not — that is your one real breaking change.
  • LockResponseLoaderResponseModifier gained an optional constructor argument. Container autowiring handles it, but manual instantiation in tests or factories needs null passed explicitly when logging is off.
  • Tune the threshold, don't minimize it. Setting logs/lock_wait_threshold to 0.1s will flood logs with normal jitter. Set it just above your p95 upstream latency.
  • Short waits are invisible. Only waits above the threshold log. Do not use log volume as your contention counter; use the awaitUnlock() return value.
  • Behavior change when caching breaks. Previously a failed store-to-cache kept the lock for its TTL; now it releases. If you were relying on the lock as an implicit circuit breaker during a cache outage, add an explicit one.
  • Debugging checklist. Grep for :lock_wait; confirm the log/store/unlock middleware appear in the reloaded request's pipeline; confirm no 423 bodies reach clients; confirm a thrown exception mid-request leaves no residual lock (check awaitUnlock() return time on the next request).
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