Home > Blockchain >  What is the best way to avoid hitting the cache repititively to access a data in a loop
What is the best way to avoid hitting the cache repititively to access a data in a loop

Time:12-18

Let's say we have a method of an Class that is being called in iteration n times, and the method in itself has a statement that pulls data from a cache system - Redis.

Now if this method is called n times the cache is also hit n times leading to a continuous fetch and unserializing of the same data n times which in the case of an interpreter like PHP consumes a good amount of time & CPU.

Passing the cached data to this method could also be a no as we might instantiate n number of instances of this class.

So is there a way where we can avoid hitting the cache multiple times in the context of a Class/Object instead if we can use the static properties of the Object to hold the value?

CodePudding user response:

First, write a service class that:

  • Provides getter, which:
    • Loads required value from cache (based on unique-key),
    • But also backups the loaded-value,
    • Finally, returns backupped-value instead of re-loading from cache.
  • Provides setter which updates both backup and cache.

Then simply use Laravel's feature to inject and/or get instance of said service-class.

(I write and/or say "backupped" instead of "backed up", because dictionary is wrong, as prove:

  • "backupped cake" remains it's meaning,
  • while "backed up cake" is confusing.)

Example

<?php

namespace App\Services;

class MyCacheService
{
    protected $backupMap = [];

    public function get($key)
    {
        $backup = & $this->backupMap[$key];
        if ( ! isset($backup)) {
            $backup = $this->rawGet($key);
        }
        return $buckup;
    }

    public function set($key, $value)
    {
        $this->rawSet($key, $value);
        $this->backupMap[$key] = $value;
    }

    /** Loads from cache */
    private function rawGet($key)
    {
        $value = null;

        // ... your normal loading from cache logic goes here.
        return $value;
    }

    /** Saves into cache */
    private function rawSet($key, $value)
    {
        // ... your normal saving into cache logic goes here.
    }
}

Usage:

use App\Services\MyCacheService;
use Illuminate\Support\Facades\App;

// ...

// Get instance once.
/** @var MyCacheService|null $cacheService */
$cacheService = App::make(MyCacheService::class);

// Reuse as many times as required, like.
$myValue = $cacheService->get('my-unique-key');

WARNING: as you may already know, replace rawGet and rawSet's logic, of course.

Also, place MyCacheService.php file (which's source is above) in app/Services folder.

CodePudding user response:

You can use static properties to store the cached data and use access it same.

class CacheClass
{
    private static $cachedData;

    public function retrieveData()
    {
        if (!isset(self::$cachedData)) {
            // re-assign the value
            self::$cachedData = fetchDataFromCache();
        }
        
        return self::$cachedData;
    }
}
  • Related