laravel-model-caching icon indicating copy to clipboard operation
laravel-model-caching copied to clipboard

How to control failed connections with cache in order to use the DB when it's needed?

Open andreshg112 opened this issue 6 years ago • 9 comments

Issue

I would like to connect to DB when the cache connection fails or there is a timeout. Is it possible to do it? It would be like a fallback connection.

Environment

Laravel Version: 5.6.39 Laravel Model Caching Package Version: 0.3.7 PHP Version: 7.2.13 Operating System & Version: mac OS Catalina (10.15)

andreshg112 avatar Oct 21 '19 22:10 andreshg112

If cache does not resolve, it should automatically pull from DB. Are you experiencing a specific issue? If so, please provide a stack trace, and any configuration information, as well as the eloquent query, so we can try to replicate the problem. Ideally this would be in a public test repo.

mikebronner avatar Oct 21 '19 22:10 mikebronner

If I create a fake connection, I get the error below. The thing is that I would like to control or avoid cache errors, so it can connect to DB.

{
  "message": "php_network_getaddresses: getaddrinfo failed: Name or service not known",
  "exception": "RedisException",
  "file": "/var/www/vendor/laravel/framework/src/Illuminate/Redis/Connectors/PhpRedisConnector.php",
  "line": 109,
  "trace": [
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Redis/Connectors/PhpRedisConnector.php",
      "line": 109,
      "function": "connect",
      "class": "Redis",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Redis/Connectors/PhpRedisConnector.php",
      "line": 66,
      "function": "establishConnection",
      "class": "Illuminate\\Redis\\Connectors\\PhpRedisConnector",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Support/helpers.php",
      "line": 1041,
      "function": "Illuminate\\Redis\\Connectors\\{closure}",
      "class": "Illuminate\\Redis\\Connectors\\PhpRedisConnector",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Redis/Connectors/PhpRedisConnector.php",
      "line": 83,
      "function": "tap"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Redis/Connectors/PhpRedisConnector.php",
      "line": 23,
      "function": "createClient",
      "class": "Illuminate\\Redis\\Connectors\\PhpRedisConnector",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Redis/RedisManager.php",
      "line": 79,
      "function": "connect",
      "class": "Illuminate\\Redis\\Connectors\\PhpRedisConnector",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Redis/RedisManager.php",
      "line": 61,
      "function": "resolve",
      "class": "Illuminate\\Redis\\RedisManager",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Cache/RedisStore.php",
      "line": 223,
      "function": "connection",
      "class": "Illuminate\\Redis\\RedisManager",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Cache/RedisStore.php",
      "line": 54,
      "function": "connection",
      "class": "Illuminate\\Cache\\RedisStore",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Cache/Repository.php",
      "line": 86,
      "function": "get",
      "class": "Illuminate\\Cache\\RedisStore",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/genealabs/laravel-model-caching/src/Traits/Caching.php",
      "line": 116,
      "function": "get",
      "class": "Illuminate\\Cache\\Repository",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/genealabs/laravel-model-caching/src/Traits/Caching.php",
      "line": 99,
      "function": "getCacheCooldownDetails",
      "class": "GeneaLabs\\LaravelModelCaching\\CachedBuilder",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/genealabs/laravel-model-caching/src/Traits/Caching.php",
      "line": 128,
      "function": "getModelCacheCooldown",
      "class": "GeneaLabs\\LaravelModelCaching\\CachedBuilder",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/genealabs/laravel-model-caching/src/CachedBuilder.php",
      "line": 278,
      "function": "checkCooldownAndRemoveIfExpired",
      "class": "GeneaLabs\\LaravelModelCaching\\CachedBuilder",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/genealabs/laravel-model-caching/src/CachedBuilder.php",
      "line": 233,
      "function": "retrieveCachedValue",
      "class": "GeneaLabs\\LaravelModelCaching\\CachedBuilder",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/genealabs/laravel-model-caching/src/CachedBuilder.php",
      "line": 162,
      "function": "cachedValue",
      "class": "GeneaLabs\\LaravelModelCaching\\CachedBuilder",
      "type": "->"
    },
    {
      "file": "/var/www/app/Http/Controllers/AltRoutesController.php",
      "line": 70,
      "function": "paginate",
      "class": "GeneaLabs\\LaravelModelCaching\\CachedBuilder",
      "type": "->"
    },
    {
      "function": "index",
      "class": "App\\Http\\Controllers\\AltRoutesController",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Controller.php",
      "line": 54,
      "function": "call_user_func_array"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php",
      "line": 45,
      "function": "callAction",
      "class": "Illuminate\\Routing\\Controller",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
      "line": 212,
      "function": "dispatch",
      "class": "Illuminate\\Routing\\ControllerDispatcher",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
      "line": 169,
      "function": "runController",
      "class": "Illuminate\\Routing\\Route",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
      "line": 665,
      "function": "run",
      "class": "Illuminate\\Routing\\Route",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 30,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Router",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/barryvdh/laravel-cors/src/HandleCors.php",
      "line": 36,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 151,
      "function": "handle",
      "class": "Barryvdh\\Cors\\HandleCors",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 53,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php",
      "line": 41,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 151,
      "function": "handle",
      "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 53,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 104,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
      "line": 667,
      "function": "then",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
      "line": 642,
      "function": "runRouteWithinStack",
      "class": "Illuminate\\Routing\\Router",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
      "line": 608,
      "function": "runRoute",
      "class": "Illuminate\\Routing\\Router",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
      "line": 597,
      "function": "dispatchToRoute",
      "class": "Illuminate\\Routing\\Router",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
      "line": 176,
      "function": "dispatch",
      "class": "Illuminate\\Routing\\Router",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 30,
      "function": "Illuminate\\Foundation\\Http\\{closure}",
      "class": "Illuminate\\Foundation\\Http\\Kernel",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/fideloper/proxy/src/TrustProxies.php",
      "line": 57,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 151,
      "function": "handle",
      "class": "Fideloper\\Proxy\\TrustProxies",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 53,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
      "line": 31,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 151,
      "function": "handle",
      "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 53,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
      "line": 31,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 151,
      "function": "handle",
      "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 53,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php",
      "line": 27,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 151,
      "function": "handle",
      "class": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 53,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php",
      "line": 62,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 151,
      "function": "handle",
      "class": "Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 53,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/barryvdh/laravel-cors/src/HandlePreflight.php",
      "line": 29,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 151,
      "function": "handle",
      "class": "Barryvdh\\Cors\\HandlePreflight",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
      "line": 53,
      "function": "Illuminate\\Pipeline\\{closure}",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
      "line": 104,
      "function": "Illuminate\\Routing\\{closure}",
      "class": "Illuminate\\Routing\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
      "line": 151,
      "function": "then",
      "class": "Illuminate\\Pipeline\\Pipeline",
      "type": "->"
    },
    {
      "file": "/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
      "line": 116,
      "function": "sendRequestThroughRouter",
      "class": "Illuminate\\Foundation\\Http\\Kernel",
      "type": "->"
    },
    {
      "file": "/var/www/public/index.php",
      "line": 55,
      "function": "handle",
      "class": "Illuminate\\Foundation\\Http\\Kernel",
      "type": "->"
    }
  ]
}

andreshg112 avatar Oct 21 '19 22:10 andreshg112

@andreshg112 Not sure how possible that is at the moment. Thanks for submitting this use-case. I can see this would come in handy if the Redis server unexpectantly was offline.

mikebronner avatar Oct 21 '19 22:10 mikebronner

What files should I change in order to achieve this? So I could create a pull requests.

andreshg112 avatar Oct 22 '19 01:10 andreshg112

@andreshg112 Sorry, at this time I have no idea, it would be something I have to research. My best suggestion for now would be to start playing around through trial and error, and maybe submitting a PR with your findings. :)

mikebronner avatar Oct 22 '19 01:10 mikebronner

I'm also curious about this, as I'm having occasional silent cache purge failures with Redis. It does not seem to throw any uncaught exception within that request, but once the page reloads, it's clear that the cache was not invalidated, and old values are showing on the screen that do not match the database. This is creating serious intermittent data integrity issues.

Does anyone have any thoughts on whether this seems odd? I would think Redis would throw a hard error if you tried to write to it and it failed, or at least allow us to intercept and retry or something.

zlanich avatar Jul 14 '20 17:07 zlanich

@zlanich Thanks for the adding your observations! Can you think of a way we could reproduce this problem consistently?

mikebronner avatar Jul 14 '20 18:07 mikebronner

@mikebronner I wish I could. It was reported to us in our production environment, and we could not reproduce it, leading me to believe that the purge fails on occasion. I'm assuming it's due to a Redis connection error, but since it's not reporting anything when this happens, I can't be certain.

For now, I ended up writing custom middlewares, etc and disabling model cache in our admin UI and on write endpoints in the mobile app API just to minimize the effect. I also upgraded from predis to phpredis hoping it would help in some way.

This is tough thing, because it really needs addressed, but it's intermittent. Gah!

zlanich avatar Jul 14 '20 18:07 zlanich

I'm facing similar issue when Redis server is down. Tested by manually stopping the Redis server.

Here's the log: Connection refused {"exception":"[object] (RedisException(code: 0): Connection refused at [path_to_web_root]/vendor/laravel/framework/src/Illuminate/Redis/Connectors/PhpRedisConnector.php:161)"}

Laravel version: 10.x (Using phpredis extension) Redis version: 6.2.7 (Standalone)

geniqtech avatar Apr 04 '23 08:04 geniqtech