juanparati/laravel-timeout
最新稳定版本:0.8
Composer 安装命令:
composer require juanparati/laravel-timeout
包简介
Set a timeout to your queries.
README 文档
README
Laravel Query Timeout ⏰
A Laravel database extension that implements query timeouts at the database level, helping you implement the circuit breaker pattern.
Note: This library only supports MariaDB and MySQL databases.
How it works.
Use the \DB::timeout method to set a maximum execution time for your queries:
\DB::timeout( 3 , // Interrupt if a query takes more than 3 seconds fn() => \DB::select('SELECT SLEEP(4)'), // Your query comes here 'myconnection' // Keep null for the default connection );
In the previous example if the query exceeds the specified timeout (3 seconds), it will be terminated and throw a \Juanparati\LaravelTimeout\QueryTimeoutException.
How it works under the hood
Instead of using co-routines or parallel execution monitoring, this library leverages native database features:
- MariaDB: max_statement_time
- MySQL: max_execution_time
The timeout mechanism works by:
- Setting the timeout value for the database session
- Executing the query
- Restoring the original timeout value
╔════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ Example flow for MariaDB ║
║ ║
║ ┌─────────────────────────────────────────┐ ║
║ 1.│SET @@SESSION.max_statement_time=3; │ ◀─── Set the desired maximum time for the session ║
║ └─────────────────────────────────────────┘ ║
║ ┌─────────────────────────────────────────┐ ║
║ 2.│SELECT * FROM USERS; │ ◀─── Execute the query ║
║ └─────────────────────────────────────────┘ ║
║ ┌─────────────────────────────────────────┐ ║
║ 3.│SET @@SESSION.max_statement_time=0; │ ◀─── Restore the original session maximum time ║
║ └─────────────────────────────────────────┘ ║
╚════════════════════════════════════════════════════════════════════════════════════════════════════╝
Limitations
MySQL-specific
- Only "select" queries are timed out in MySQL.
- Unfortunately, MySQL kills the query silently without raising any error and always returns an empty result, so the way that laravel-timeout determines when a query was in reality timed out it's measuring the execution time and creating artificially an exception, so I recommend run only one single query inside the closure when MySQL is used.
MariaDB-specific
- Old MariaDB embedded servers may not work properly.
- COMMIT statements don't timeout in Galera clusters.
General Limitations:
- May be unreliable with persistent connections or connection pools in distributed environments
Best Practices
- Keep application logic outside the closure.
✅ Recommended:
$users = null; \DB::timeout( 5, fn() => $users = User::where('name', 'like', 'john%')->get() ); foreach ($users as $user) { if ($user->password_expiration > now()) { ... // Your application logic } }
❌ Not recommended:
\DB::timeout( 5, function() { $users = User::where('name', 'like', 'john%')->get() foreach ($users as $user) { if ($user->password_expiration > now()) { ... // Your application logic } } } );
- In MySQL, try to use only one query per closure (Be cautious with ORM operations that might trigger multiple queries).
Configuration
Publish configuration (Optional)
artisan vendor:publish --tag="timeout"
统计信息
- 总下载量: 2
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-06-17