Giter VIP home page Giter VIP logo

laravel-swr-cache's Introduction

Laravel Cache Stale-While-Revalidate

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

There are applications out there that rely heavily on cache to improve performance, and thanks to Laravel's cache()->remember() method, we can easily cache the result of a callback for a given Time-To-Live (TTL).

However, there are cases when the callback may take a long time to execute, and we don't want to wait for it to finish before giving a response back to the user.

This is where the Stale-While-Revalidate pattern comes in handy. It allows us to return a cached result immediately, and then execute the callback in the background to update the cache for the next request.

How does SWR works under the hood?
flowchart TD
    Request[Request key from cache] --> CacheHit{Is the given key available in cache?}

    CacheHit -->|No| FirstTimeProcess[Execute long process]
    FirstTimeProcess --> FirstTimeCache[Cache result]
    FirstTimeCache --> Response

    CacheHit -->|Yes| CacheStale{Is it stale?}
    CacheStale -->|No| ObtainCache[Get fresh value from cache]
    ObtainCache --> Response

    CacheStale --> |Yes| ObtainStaleCache
        ObtainStaleCache[Get stale value from cache] --> Response
        
        ObtainStaleCache -.- Background
        subgraph Background[After response]
            LongProcess[Execute long process] --> CacheResult[Cache result]
        end

    Response[Return value] --> Continue[/.../]

Installation

You can install the package via composer:

composer require iksaku/laravel-swr-cache

Usage

The swr() method is a wrapper around cache()->remember() that adds support for the Stale-While-Revalidate pattern using a new Time-To-Stale argument (TTS). You can access this method using the cache() helper function:

$stats = cache()->swr(
    key: 'stats',
    ttl: now()->addHour(),
    tts: now()->addMinutes(15),
    callback: function () {
        // This may take a couple of seconds...
    }
);

// ...

Or using the Cache facade:

$stats = \Illuminate\Support\Facades\Cache::swr(
    key: 'stats',
    ttl: now()->addHour(),
    tts: now()->addMinutes(15),
    callback: function () {
        // This may take a couple of seconds...
    }
);

// ...

Like the remember() method, if the value is not available in cache, the callback will be executed and the result will be cached for the given Time-To-Live and the corresponding Time-To-Stale will also be stored.

If the value is available and the Time-To-Stale has not passed, the value is considered fresh and will be returned immediately. The callback will not be executed.

If the Time-To-Stale has passed, the value is considered stale, it will be returned immediately, and the callback will be executed after the response is sent to the user.

Tip

Mohamed Said has a great post on this. Check it out: Running a task after the response is sent.

Queueing the callback execution

If you prefer to queue the callback execution instead of running it after the response is sent, you can use the queue argument:

$stats = cache()->swr(
    key: 'stats',
    ttl: now()->addHour(),
    tts: now()->addMinutes(15),
    callback: function () {
        // This may take more than a couple of seconds...
    },
    queue: true
);

And, if you want to further customize the queued job, you can pass on a closure that accepts a parameter of type Illuminate\Foundation\Bus\PendingClosureDispatch:

use Illuminate/Foundation/Bus/PendingClosureDispatch;

$stats = cache()->swr(
    key: 'stats',
    ttl: now()->addHour(),
    tts: now()->addMinutes(15),
    callback: function () {
        // This may take more than a couple of seconds...
    },
    queue: function (PendingClosureDispatch $job) {
        $job->onQueue('high-priority')
    }
);

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.

laravel-swr-cache's People

Contributors

iksaku avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar

laravel-swr-cache's Issues

[Bug]: Laravel 10 support?

What happened?

When tried to install on Laravel 10 I've got error:

iksaku/laravel-swr-cache 1.0.0 requires illuminate/contracts ^9.0 -> found illuminate/contracts[v9.0.0, ..., v9.52.16] but these were not loaded, likely because it conflicts with another require.

How to reproduce the bug

Install with Laravel 10

Package Version

1.0

PHP Version

8.2

Laravel Version

10

Which operating systems does with happen with?

No response

Notes

No response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.