Tempest is still a work in progress. Visit our GitHub or Discord

Caching

Tempest comes with a simple wrapper around PSR-6, which means you can use all PSR-6 compliant cache pools. Tempest uses Symfony's Cache Component as a default implementation, so all of Symfony's adapters are available out of the box.

Configuration

Tempest will use file caching by default. You can however configure another adapter via CacheConfig:

// app/Config/cache.config.php

use Tempest\Cache\CacheConfig;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;

return new CacheConfig(
    pool: new FilesystemAdapter(
        namespace: '',
        defaultLifetime: 0,
        directory: __DIR__ . '/../../../../.cache',
    ),
);

Caching

To be able to cache stuff, you need to inject the Cache interface wherever you need it, and you're ready to go:

// app/RssController.php

use Tempest\Cache\Cache;
use Tempest\Http\Response;

final readonly class RssController
{
    public function __construct(
        private Cache $cache
    ) {}
    
    public function __invoke(): Response
    {
        $rss = $this->cache->resolve(
            key: 'rss',
            cache: function () {
                return file_get_contents('https://stitcher.io/rss')
            },
            expiresAt: (new DateTimeImmutable())->add(new DateInterval('P1D'))
        )
    }   
}

If you need more fine-grained control, the Cache interface has the following methods:

  • resolve(string $key, Closure $cache, ?DateTimeInterface $expiresAt = null): mixed — to retrieve an item from cache, it'll be cached automatically if it wasn't yet.
  • put(string $key, mixed $value, ?DateTimeInterface $expiresAt = null): CacheItemInterface — to get an item from cache. Note that this method will always return CacheItemInterface, even if there wasn't a hit (thanks PSR-6!). Use $item->isHit() to know whether it's valid or not.
  • get(string $key): mixed — get an item from cache, returns null if there wasn't a hit.
  • remove(string $key): void — removes an item from cache.
  • clear(): void — clears the cache in full.

Custom caches

It's important to note that the pool configured in CacheConfig is used for the default cache, also known as the project cache. If needed, you can create your own caches with different adapters like so:

// app/RedisCache.php

use Tempest\Container\Singleton;
use Tempest\Cache\Cache;
use Tempest\Cache\IsCache;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\RedisAdapter;

#[Singleton]
final readonly class RedisCache implements Cache
{
    use IsCache;
    
    protected function getCachePool(): CacheItemPoolInterface
    {
        return new RedisAdapter(/* … */)
    }
}

In fact, Tempest comes with two other internal caches besides the project cache: ViewCache and DiscoveryCache. Both caches are used for internally by the framework, but can of course be cleared by users as well.

Clearing caches

Tempest comes with a cache:clear command which allows you to pick which caches you want to clear:

./tempest cache:clear

Which caches do you want to clear? 
> [ ] Tempest\Core\DiscoveryCache
  [ ] Tempest\Core\ConfigCache
  [ ] Tempest\View\ViewCache
  [ ] Tempest\Cache\ProjectCache
  [ ] 

If you want to clear all caches, you can use the --all flag:

./tempest cache:clear --all

Tempest\Core\DiscoveryCache cleared successfully
Tempest\Core\ConfigCache cleared successfully
Tempest\View\ViewCache cleared successfully
Tempest\Cache\ProjectCache cleared successfully
 cleared successfully

Done 

It's recommended that you clear all caches on deployment.

Enabling or disabling caches

It's likely that you don't want caches enabled in your local environment. Tempest comes with a couple of environment flags to manage whether caching is enabled or not. If you want to enable or disable all caches at once, you can use the CACHE environment variable:

CACHE=true

If, however, you need more fine-grained control over which caches are enabled or not, you can use the individual environment toggles. Note that, in order for these to work, the CACHE must be set to null!

# The CACHE key is used as a global override to turn all caches on or off
# Should be true in production, but null or false in local development
CACHE=null

# Enable or disable discovery cache
DISCOVERY_CACHE=false

# Enable or disable config cache
CONFIG_CACHE=false

# Enable or disable view cache
VIEW_CACHE=false

# Enable or disable project cache (allround cache)
PROJECT_CACHE=false

It's recommended to always set CACHE=true in production.

Finally, you can use the cache:status command to verify which cashes are enabled and which are not:

./tempest cache:status

Tempest\Core\DiscoveryCache enabled
Tempest\Core\ConfigCache enabled
Tempest\View\ViewCache disabled
Tempest\Cache\ProjectCache disabled