Skip to content

Instantly share code, notes, and snippets.

@kmccarth
Last active June 4, 2017 15:12
Show Gist options
  • Save kmccarth/2fbd3e18c4266561260d344b80797f80 to your computer and use it in GitHub Desktop.
Save kmccarth/2fbd3e18c4266561260d344b80797f80 to your computer and use it in GitHub Desktop.
learnMeSomeCache.md

Caching at VA

http://imgur.com/a/mCssj

tl;dr

  • We're starting first by leveraging Controller-based caching.
  • Drops the big chats call from iOS to drop from 7 seconds to 1 second on local
  • @Joe: need to add $tags to all Cacheable things, and Models.
  • @Joe: need to incoreporate "skipCaching" on $request
  • @Joe: need to invalidate the $tags
  • @Joe: we should trigger a Listener on CacheKeyWritten or whatever that pushes the JSON to S3
  • off of ios_links in API, and JB's rip_storage in Web,

Strategies

There are several different entry points into the tech stack that we could feasibly cache. Here are some notes on each relate to us

HTTP

  • plugins include spaite's response-cache
  • doesn't work well with v2 routes (b/c caching works at route-level, not posted-json-level)
interface CacheProfile
{
    /*
     * Determine if the response cache middleware should be enabled.
     */
    public function enabled(Request $request): bool;

    /*
     * Determine if the given request should be cached.
     */
    public function shouldCacheRequest(Request $request): bool;

    /*
     * Determine if the given response should be cached.
     */
    public function shouldCacheResponse(Response $response): bool;

    /*
     * Return the time when the cache must be invalidated.
     */
    public function cacheRequestUntil(Request $request): DateTime;

    /**
     * Return a string to differentiate this request from others.
     *
     * For example: if you want a different cache per user you could return the id of
     * the logged in user.
     *
     * @param \Illuminate\Http\Request $request
     *
     * @return mixed
     */
    public function cacheNameSuffix(Request $request);
}

Controllers

  • object caching
  • reliable
  • easy to incorporate, assuming everything else is done correctly.
class IndexController extends BaseController
{
    public function index(Request $request)
    {
      $key = 'bigCall.'.(Auth::user())->id;
      $minutes = 60;
      return \Cache::remember($key, $minutes, function () use ($request) {
          return $this->bigCall($request);
      });
    }

    public function bigCall($request)
    {
        /*...*/
        return $any;
    }

Repositories

  • object-based
  • kind of wonky with our env
use Prettus\Repository\Eloquent\BaseRepository;
use Prettus\Repository\Contracts\CacheableInterface;
use Prettus\Repository\Traits\CacheableRepository;

class PostRepository extends BaseRepository implements CacheableInterface {

    use CacheableRepository;

    ...
}

Models

  • caching database-queries
  • plugins generally won't cache raw $sql in the code-base, only ORM-specific.
  • need to cache either every Modal in the namespace, or none.
  • plugin options: InfinityModel, Lada-Cache
class User extends \SomeBaseModelClass
{
  /*...*\
}

Fundamentals:

To grab OR build/set a Cache, please use the remember method:

Cache::remember($key, $minutes, $closure());

You may wish to retrieve all users from the cache or, if they don't exist, retrieve them from the database and add them to the cache:

$key = 'all_users';
$minutes = 60;
$all_users = Cache::remember($key, $minutes, function () {
  return User::all();
});

Copy-and-paste-able:

$key = time();
$minutes = 1;
return \Cache::remember($key, $minutes, function () use ($key) {
    return time();
});

Roadmap

  • Building JSON and ship JSON to S3 so Cloudfront could hypotheticall serve it
  • Catchall endpoint to grab everything in a user's cache
  • Get iOS/Angular teams to leverage eTags
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment