惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

I
InfoQ
Last Week in AI
Last Week in AI
大猫的无限游戏
大猫的无限游戏
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
V
V2EX
D
Darknet – Hacking Tools, Hacker News & Cyber Security
WordPress大学
WordPress大学
H
Help Net Security
P
Proofpoint News Feed
B
Blog
腾讯CDC
博客园 - 司徒正美
Recorded Future
Recorded Future
酷 壳 – CoolShell
酷 壳 – CoolShell
S
Security Archives - TechRepublic
N
News and Events Feed by Topic
T
The Exploit Database - CXSecurity.com
www.infosecurity-magazine.com
www.infosecurity-magazine.com
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
O
OpenAI News
GbyAI
GbyAI
Attack and Defense Labs
Attack and Defense Labs
T
Troy Hunt's Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
F
Future of Privacy Forum
V
Vulnerabilities – Threatpost
T
Threatpost
The Cloudflare Blog
Recent Announcements
Recent Announcements
爱范儿
爱范儿
S
Schneier on Security
Blog — PlanetScale
Blog — PlanetScale
Cyberwarzone
Cyberwarzone
T
The Blog of Author Tim Ferriss
T
True Tiger Recordings
P
Proofpoint News Feed
S
Secure Thoughts
F
Fox-IT International blog
aimingoo的专栏
aimingoo的专栏
阮一峰的网络日志
阮一峰的网络日志
M
Microsoft Research Blog - Microsoft Research
F
Full Disclosure
Google Online Security Blog
Google Online Security Blog
T
Threat Research - Cisco Blogs
S
Securelist
罗磊的独立博客
L
Lohrmann on Cybersecurity
博客园 - 三生石上(FineUI控件)
T
Tailwind CSS Blog
MongoDB | Blog
MongoDB | Blog

DEV Community

Why Google Can't See Your React Breadcrumbs (And the 4-Line Fix) AI Travel Assistant Powered by Gemma 4; With Streaming, Image Input, and Visual Recommendation Cards Microsoft tried to kill the printer driver. Healthcare said no. The Blueprint Beneath the Blueprint: Designing Data Model and Choosing Its Database REST APIs vs Webhooks in Telecom Billing - Which One Actually Makes Sense? Accounting Made Simple: AI-Powered Financial Insights of Japanese Companies with Gemma 4 The append-only AST trick that makes Flutter AI chat actually smooth Designing the Future of Payments — Why XML Still Matters in the Age of APIs From Legacy to Live — Reviving XMLPayments with GitHub Copilot Two Weeks Into Learning Solana XMLPayments — The Hidden Backbone of Modern Financial Orchestration AI Agents in Practice — Read from the beginning Reviving My Gemma Agentic Framework: From Prototype to Polished Repo Smart Contracts Demand Better Infrastructure: Building on contract.dev Self-Hosted LLM Tool Calling: Forge and the Build-vs-Buy Decision ORA-00072 오류 원인과 해결 방법 완벽 가이드 OpenWA for CTOs: Self-Hosted WhatsApp Gateway Trade-Offs NotebookLM Automation With notebooklm-py: Useful, But Classify Data First Docker v29.5.x Operator Upgrade Checklist Coding-Agent Instruction Design: The CLAUDE.md File That Prevents Rework When I Finally Realized My Runtime Was Holding Me Back GnokeOps: Host Your Own AI House Party The Death of Static Rate Limiters: Why Your Java Virtual Threads Need BBR-Style Adaptive Concurrency AI Agents in Practice — Part 2: What Makes Something an Agent Stop scattering LLM SDK/API calls across your codebase. Here is the 2-file rule that fixed mine Beyond Prompts: Structuring AI Workflows for Real Frontend Engineering From an Abandoned Hackathon Project to an AI Study Workspace 🚀 Terraform with AI: Build AWS Infra (Cursor + MCP) What If AI Didn’t Need the Internet? 750,000 Chips, 140 Trillion Tokens: The Math Behind DeepSeek's Permanent Price Cut You're Renting Someone Else's Compute — And It's Costing You More Than You Think CSS :has() Selector: The Layout Trick I Wish I Knew 5 Years Ago Five Clusters. Five Lessons. One Production System. Synaptic: A Local-First AI Dev Companion That Remembers How You Think Revolutionizing Edge MedTech: Building a Sovereign Sleep Apnea Companion ("XiHan Snore Coach") with Gemma 4 HDD Eksternal Tiba-Tiba Tidak Bisa Diakses di Windows? Ini Tiga Lapis Fix-nya DMARC p=none vs p=quarantine vs p=reject: what to use and when DSA Application in Real Life: How Git Diff Works: LCS Intuition, Myers Algorithm, and Real Code Changes I solo-built a reputation layer for AI agents on NEAR — and here's what I learned I built an AI faceless video generator in 2 months — here's the stack Diffusion Language Models: How NVIDIA Nemotron-Labs Diffusion Shatters the Autoregressive Speed Ceiling llm-nano-vm v0.8.0 — deterministic FSM runtime for LLM pipelines, now with output validation and per-step timeouts From the Renaissance to the Quantum Dawn: AI, Computation, and the Next Paradigm Shift How I Built a Review Site with 800+ Articles Using AI I Built a Smart Kitchen AI with Gemma 4 That Turns Fridge Photos Into Recipes Why your vulnerability dashboard is lying to you (and how to fix it) From Abandoned Prototype to Smart AI System: Reviving Trafiq AI with GitHub Copilot Why Country/State/City Pickers Are Weirdly Hard Node.js 22 LTS — EOL Date, Support Timeline, and What Comes Next The 7-Layer Memory Architecture Behind Modern AI Agents I Imagined Hermes Agent Running an Entire Smart City — And It Changed How I See AI One backend, four products: why we bet on platform-per-brand AI's tech debt is invisible — even to AI. I solved it at the architecture layer. Why ROAS 300% Can Still Mean Losses — Gross Margin in 5 Ecommerce Verticals You Don’t Need to Try Every AI Tool to Keep Up NovelPilot: A Novel Writing Agent Powered by Gemma 4 BoxAgnts is an Out-Of-The-Box Secure AI Agent ToolBox in a WASM SandBox Gemma 4 deep dive: why a 1.5 GB model scores 37.5% on competition mathematics, how the MoE routing actually works, and which model fits your hardware. Full breakdown inside. BeeLlama v0.2.0: 164 tok/s on a 27B model, one RTX 3090 Google Just Declared the Chat-Log Interface Dead. Here's What Neural Expressive Actually Signals for Developers. ARCHITECTURE SPECIFICATION & FORMAL SYSTEM REPORT: k501-AIONARC Notes from a Hammock What's Google Antigravity 2.0 ? Here's What the Agent Harness Actually Changes for Developers. Building an E2EE Chat App in Flask - Part 3: Keeping File Uploads Safe Google's Gemini Spark. Here's What It Actually Does for Developers. Microsoft Just Shipped MCP Governance for .NET. Here's What It Actually Enforces. How I Built a Pakistan Internet Speed Test Platform at 16 How to Build a Supervisor Agent Architecture Without Frameworks I Built My Own Corner of the Internet — Here's What It Looks Like How does VuReact compile Vue 3's defineExpose() to React? Neo-VECTR's Rift Ascent Idempotency Keys: The API Safety Net You Probably Aren't Using Building E-Commerce Sites for Niche Products: Technical Lessons from Specialty Outdoor Retailers Audit Logs: The Silent Guardian of Every Serious System Open-source SDS tooling for Japanese MHLW compliance: the gap nobody filled BetAGracevI I Built a Post-Quantum Cryptographic Identity SDK for AI Agents — Here's Why It Needs to Exist Running Claude Code across multiple repos without losing context There Are Cameras in Every Room of My House. I Put Them There. Why your AI agent loops forever (and how to break the cycle) How does VuReact compile Vue 3's defineSlots() to React? Building a Privacy-First Resume Editor with Typst WASM and React One Soul, Any Model: Portable Memory for Open-Source Agents with .klickd From Pixels to Prescriptions: Building an Autonomous Healthcare Booking Agent with LangGraph MonoGame - A Game Engine for Those Who Love Reinventing the Wheel # Day 24: In Solana, Everything is an Account Mastering Node.js HTTP Module: Build Servers, REST APIs, and Handle Requests Mastering Node.js HTTP Module: Build Servers, REST APIs, and Handle Requests RP2040 Wristwatch Tells Time With a Vintage VU Meter Needle observations about models / 2026, may From Video Transcripts to Source-Grounded AI Notes: A Practical Look at Notesnip AI Agent Dev Environment Guide — Real Experience from an AI Living Inside a Server How I Run 7 AI Models 24/7: Multi-Agent Architecture in Practice What exactly changes with the Claude Max plan? I Revived a Broken MLOps Platform — Now It's Self-Service, Policy-Guarded, and Operationally Credible OpenAI's $2M-tokens-for-equity YC deal, decoded Why DMX Infrastructure is Still Stuck in the 90s Agent Series (2): ReAct — The Most Important Agent Reasoning Paradigm Open Source Project (No.73): Sub2API - All-in-One Claude/OpenAI/Gemini Subscription-to-API Relay I Made the Wrong Bet on Event Streaming in Our Treasure Hunt Engine
Laravel Waiting Request
Aftabul Isla · 2026-05-23 · via DEV Community

Aftabul Islam

The Problem

You are processing some data through background job. But before the processing is done, another request had been made to read the related data.

In this case you are either providing a historic data or serving wrong information.

Solution

Holding the request until the job is executed, could be the simplest solution.
I am not saying it is the only solution, but the simplest one.

Some Scenarios

Lets discuss about some possible scenarios.

Booking Job

When a user request to book a resource between two specifics dates. Let's assume that it is done by a job. So it might take some time in production load.
In the meantime if another request is asking for that specific users booking data.

File Importing Job

User uploads a file like CSV or XML, you have accepted the file but it also needs processing, which should be done in by a job.
If the user ask for the status of the CSV resource in another request.

The Package

aihimel/laravel-waiting-request is a small Laravel package that solves exactly this — it lets one request park until another piece of work (a job, a sync, a long-running controller action) signals that the resource is ready to read.

Install

composer require aihimel/laravel-waiting-request

Enter fullscreen mode Exit fullscreen mode

Optionally publish the config:

php artisan vendor:publish --tag="waiting-request-config"

Enter fullscreen mode Exit fullscreen mode

How it works

The package exposes a tiny API around four ideas: block, wait, check, resolve. Under the hood it is backed by your Laravel cache — no extra infrastructure, no queue plumbing.

A blocker is identified by a class path and a resource id. That pair becomes a unique cache key, so blockers are per-resource (booking 42 does not interfere with booking 43).

use Aihimel\LaravelWaitingRequest\Facades\LWRequest;

// 1. Block — call this where the background work *starts*
LWRequest::addBlocker(Booking::class, $booking->id);

// 2. Wait — call this in the request that wants to read the resource
$resolved = LWRequest::whenResolved(Booking::class, $booking->id);

if ($resolved) {
    return BookingResource::make($booking->fresh());
}

return response()->json(['message' => 'Still processing, try again'], 202);

// 3. Resolve — call this when the background work finishes
LWRequest::resolveBlocker(Booking::class, $booking->id);

Enter fullscreen mode Exit fullscreen mode

You can also peek without waiting:

if (LWRequest::isBlocked(Booking::class, $booking->id)) {
    // resource is mid-flight
}

Enter fullscreen mode Exit fullscreen mode

Applying it to the scenarios

Booking job. The controller that accepts the booking calls addBlocker(Booking::class, $id) and dispatches the job. The job calls resolveBlocker(...) in its handle() (or in a finally block). Any reader that hits GET /bookings/{id} in the meantime calls whenResolved(...) first and only reads the model once the writer is done.

File importing job. Same shape: addBlocker(Import::class, $import->id) when the upload is accepted, resolveBlocker(...) when the parser finishes (success or failure — both should release). The status endpoint calls whenResolved(...) so the client gets a settled answer instead of a half-imported snapshot.

Sensible defaults you can tune

Every knob lives in config/waiting-request.php and is overridable via env:

Config Env Default What it does
cache_prefix LW_REQUEST_CACHE_PREFIX lw_request_ Namespace for cache keys
timeout LW_REQUEST_MAX_WAITING_TIME 5 How long whenResolved() waits before giving up (seconds)
check_interval LW_REQUEST_CHECK_INTERVAL 250 Poll interval inside whenResolved() (milliseconds)
max_blocking_time LW_REQUEST_MAX_BLOCKING_TIME 10 Max lifetime of a blocker before it auto-expires (seconds)

addBlocker() takes an optional third argument so you can bump the TTL per call when you know a particular job runs longer:

LWRequest::addBlocker(Import::class, $import->id, 120); // 2 minutes

Enter fullscreen mode Exit fullscreen mode

Why the blocker has a lifetime

If a job crashes before calling resolveBlocker(), you do not want readers to wait forever. From v2.x every blocker carries a Unix expiry timestamp. The next isBlocked() / whenResolved() call after that timestamp will:

  1. Forget the cache entry, and
  2. Emit Log::warning('Waiting-request blocker expired without being resolved', [...])

So even if your job dies, traffic recovers on its own and you get a log line telling you it happened.

Do's and Don'ts

Do

  • Do release the blocker in finally. Wrap your job body so a thrown exception still hits resolveBlocker(). Auto-expiry is a backstop, not a happy path.
  • Do set max_blocking_time to comfortably exceed your worst-case job duration. If your import averages 8s and worst-cases at 25s, a 10s default will auto-release while the job is still running — defeating the lock.
  • Do tune timeout to match your UX budget. If a client is willing to wait 2s for a synchronous response, set timeout=2; do not let whenResolved() hold an HTTP worker for 30s.
  • Do flush the cache when upgrading from 1.x to 2.x. Pre-upgrade values stored as true will be read as 1, treated as already-expired, and produce a one-time burst of warning logs.
  • Do treat a false return from whenResolved() as "still pending". Respond with 202 Accepted (or similar) and let the client poll — do not pretend the data is ready.

Don't

  • Don't put isBlocked() on a hot, read-only path you expect to be side-effect-free. It evicts expired entries and writes a log line. That is intentional, but worth knowing.
  • Don't use it as a distributed mutex for writes. This package is for readers waiting on writers on a best-effort basis. If two writers race, Cache::add() will reject the second addBlocker() (it returns false), but the package does not give you queueing, fairness, or strict mutual exclusion.
  • Don't share a single blocker across unrelated resources. Key it by the real resource (Booking::class + $id), not by something coarse like the user id, or you will block requests that have nothing to do with each other.
  • Don't forget the cache driver matters. array or file drivers will not work across processes. In production, use redis / memcached so the worker that resolves the blocker and the web process that is waiting actually share the same cache.
  • Don't lean on whenResolved() from a queue worker. Polling inside a worker burns a worker slot. Workers should resolve blockers, not wait on them.

That's the whole package — a couple of facade calls, a cache key per resource, and a sane expiry so nothing wedges. If you've ever shipped a ?retry=true hack or a sleep-and-pray in a controller, this is the cleaner version of that.

Source & issues: github.com/aihimel/laravel-waiting-request