Package Data | |
---|---|
Maintainer Username: | mpyw |
Maintainer Contact: | ryosuke_i_628@yahoo.co.jp (mpyw) |
Package Create Date: | 2019-10-01 |
Package Last Update: | 2023-11-21 |
Home Page: | |
Language: | PHP |
License: | MIT |
Last Refreshed: | 2024-11-20 03:02:46 |
Package Statistics | |
---|---|
Total Downloads: | 214,216 |
Monthly Downloads: | 3,274 |
Daily Downloads: | 201 |
Total Stars: | 82 |
Total Watchers: | 9 |
Total Forks: | 5 |
Total Open Issues: | 0 |
Guarantee database stickiness over the same user's consecutive requests.
composer require mpyw/laravel-cached-database-stickiness
The default implementation is provided by ConnectionServiceProvider
, however, package discovery is not available.
Be careful that you MUST register it in config/app.php
by yourself.
<?php
return [
/* ... */
'providers' => [
/* ... */
Mpyw\LaravelCachedDatabaseStickiness\ConnectionServiceProvider::class,
/* ... */
],
/* ... */
];
Then select the proper cache driver:
| Driver | Is eligible? | Description |
|:---|:---:|:---|
| redis
| 😄 | Very fast, scalable and reliable driver |
| memcached
| 😄 | Alternative for Redis |
| dynamodb
| 😃 | It works but not so suitable for short-term caching |
| apc
| 😧 | It works unless PHP processes are running in multiple machines or containers |
| file
| 😧 | It works unless PHP processes are running in multiple machines or containers |
| database
| 🤮 | We'll get into a chicken-or-egg situation |
| array
| 🤮 | Just for testing |
This library provides the following features.
ShouldAssumeFresh
on your Queueable (jobs, listeners, notifications and mailables).The default stickiness TTL is 5
seconds.
You can configure this value to add stickiness_ttl
directive to your config/database.php
.
<?php
return [
/* ... */
'default' => env('DB_CONNECTION', 'mysql'),
/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/
'connections' => [
/* ... */
'mysql' => [
'read' => env('DB_HOST_READONLY') ? [
'host' => env('DB_HOST_READONLY'),
] : null,
'write' => [],
'sticky' => (bool)env('DB_HOST_READONLY'),
'stickiness_ttl' => 3, // Set the stickiness TTL to 3 seconds
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
/* ... */
],
],
];
You can configure Connection implementation.
ConnectionServiceProvider
to be removed from config/app.php
.DispatchesConnectionEvents
trait by yourself.<?php
namespace App\Providers;
use App\Database\MySqlConnection;
use Illuminate\Database\Connection;
use Illuminate\Support\ServiceProvider;
class DatabaseServiceProvider extends ServiceProvider
{
public function register(): void
{
Connection::resolverFor('mysql', function (...$parameters) {
return new MySqlConnection(...$parameters);
});
}
}
<?php
namespace App\Database;
use Illuminate\Database\Connection as BaseMySqlConnection;
use Mpyw\LaravelCachedDatabaseStickiness\DispatchesConnectionEvents;
class MySqlConnection extends BaseMySqlConnection
{
use DispatchesConnectionEvents;
}
You can register the StickinessResolverInterface
implementation to change the source for stickiness determination.
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Mpyw\LaravelCachedDatabaseStickiness\StickinessResolvers\AuthBasedResolver;
use Mpyw\LaravelCachedDatabaseStickiness\StickinessResolvers\StickinessResolverInterface;
class DatabaseServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->bind(StickinessResolverInterface::class, AuthBasedResolver::class);
}
}
| | Source | Middleware |
|:---:|:---:|:---:|
| IpBasedResolver
(Default)| Remote IP address | |
| AuthBasedResolver
| Authenticated User ID | Required |
You must add ResolveStickinessOnResolvedConnections
middleware after Authenticate
when you use AuthBasedResolver
.
--- a/app/Http/Kernel.php
+++ b/app/Http/Kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/* ... */
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
+
+ 'auth' => [
+ \App\Http\Middleware\Authenticate::class,
+ \Mpyw\LaravelCachedDatabaseStickiness\Http\Middleware\ResolveStickinessOnResolvedConnections::class,
+ ],
+
+ 'auth.basic' => [
+ \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
+ \Mpyw\LaravelCachedDatabaseStickiness\Http\Middleware\ResolveStickinessOnResolvedConnections::class,
+ ],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
- 'auth' => \App\Http\Middleware\Authenticate::class,
- 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
/* ... */
}
You can register the JobInitializerInterface
implementation to change workers' behavior.
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Mpyw\LaravelCachedDatabaseStickiness\JobInitializers\AlwaysFreshInitializer;
use Mpyw\LaravelCachedDatabaseStickiness\JobInitializers\JobInitializerInterface;
class DatabaseServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->bind(JobInitializerInterface::class, AlwaysFreshInitializer::class);
}
}
| | General Queueable | ShouldAssumeFresh
Queueable | ShouldAssumeModified
Queueable |
|:---:|:---:|:---:|:---:|
| AlwaysModifiedInitializer
(Default)| Master | Slave | Master |
| AlwaysFreshInitializer
| Slave | Slave | Master |
Schema::defaultStringLength()
in ServiceProvider::boot()
Assume that you have the following ServiceProvider
.
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Schema::defaultStringLength(191);
}
}
If you run composer install
or directly call php artisan pacakge:discover
, it will unexpectedly use caches. It will trigger errors when we execute the command in the environment unreachable to the cache repository.
RedisException : Operation timed out
Directly use Illuminate\Database\Schema\Builder
. Don't call via Illuminate\Support\Facades\Schema
Facade.
<?php
namespace App\Providers;
-use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Builder as SchemaBuilder;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
- Schema::defaultStringLength(191);
+ SchemaBuilder::defaultStringLength(191);
}
}