codefocus/managedcache

Self-invalidating cache for Laravel

dev-master / 0.1.0.x-dev 2017-08-23 08:14 UTC

This package is not auto-updated.

Last update: 2020-11-28 06:48:06 UTC


README

Latest Version on Packagist Software License Build Status Code coverage Quality Score StyleCI Total Downloads

ManagedCache

"There are only two hard problems in Computer Science: cache invalidation and naming things."

-- Phil Karlton

ManagedCache solves one of these.

When caching data (say, a fully hydrated User with all of its related data -- roles, subscriptions, preferences, etc.), you would normally have to invalidate that cache in every part of the code where one of those roles, subscriptions or preferences is modified.

ManagedCache lets you define the invalidation criteria in the same statement that caches the data.

Requirements

Cache driver requirements

ManagedCache uses tags to perform its automatic event-based invalidation. This means that your cache driver should support tags (the file and database drivers do not).

ManagedCache currently only supports the Memcached cache driver. Support for other cache drivers such as Redis is planned.

Model requirements

Models that are used in invalidation conditions should have an integer primary key.

Install

Via Composer

$ composer require codefocus/managedcache

Quick start

Provider

Add ManagedCacheProvider to the "providers" array in config/app.php

Codefocus\ManagedCache\Providers\ManagedCacheProvider::class

Facade

ManagedCache also provides a Facade.

To use it, add Codefocus\ManagedCache\Facades\ManagedCache to your use statements.

Usage

Compatibility

ManagedCache implements the Illuminate\Contracts\Cache\Store interface, and can be used as a drop-in replacement for the Cache Facade.

//  Retrieve a user.
$user = User::with(['roles', 'subscriptions', 'preferences'])->find($userId);

//  Store data as you normally would.
$cacheKey = 'users(' . $userId . ')';
ManagedCache::put($cacheKey, $user, 120);

...

//  Retrieve data as you normally would.
$user = ManagedCache::get($cacheKey);

Automatic invalidation

To automatically invalidate this data, call the setForgetConditions() function at the start of the function chain, passing in an array of invalidation conditions.

These invalidation conditions (Codefocus\ManagedCache\Condition objects) are named after the Eloquent events that trigger them, and can be created with intuitive helper functions:

//  Store data, and invalidate this cache when one of these conditions is met:
//  - This User is deleted
//  - This User is updated
//  - A Role is attached to this User
//  - A Role is detached from this User
//  - A Role attached to this User is updated
//  - A Subscription is attached to this User
//  - A Subscription is detached from this User
//  - A Subscription attached to this User is updated
//  - A Preference is attached to this User
//  - A Preference is detached from this User
//  - A Preference attached to this User is updated
ManagedCache
    ::setForgetConditions(function ($conditionBuilder) use ($user) {
        return $conditionBuilder
            ->modelDeleted($user)
            ->modelUpdated($user)
            ->relatedModelAttached($user, Role::class)
            ->relatedModelDetached($user, Role::class)
            ->relatedModelUpdated($user, Role::class)
            ->relatedModelAttached($user, Subscription::class)
            ->relatedModelDetached($user, Subscription::class)
            ->relatedModelUpdated($user, Subscription::class)
            ->relatedModelAttached($user, Preference::class)
            ->relatedModelDetached($user, Preference::class)
            ->relatedModelUpdated($user, Preference::class);
    })
    ->put($cacheKey, $user, 120);

As you can see, more complex data with many invalidation conditions could get cumbersome to define. To invalidate a cache key on any of the Eloquent events (created, updated, saved, deleted or restored) for the specified Model class or instance, use anyModelEvent() and anyRelatedModelEvent():

//  Store data, and invalidate this cache when one of these conditions is met:
//  - This User is created, updated, saved, deleted or restored
//  - A Role attached to this User is created, updated, saved, deleted or restored
//  - A Subscription attached to this User is created, updated, saved, deleted or restored
//  - A Preference attached to this User is created, updated, saved, deleted or restored
ManagedCache
    ::setForgetConditions(function ($conditionBuilder) use ($user) {
        return $conditionBuilder
            ->anyModelEvent($user)
            ->anyRelatedModelEvent($user, Role::class)
            ->anyRelatedModelEvent($user, Subscription::class)
            ->anyRelatedModelEvent($user, Preference::class);
    })
    ->put($cacheKey, $user, 120);

Change log

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

Testing

$ composer test

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email info@codefocus.ca instead of using the issue tracker.

Credits

License

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