Skip to content

Commit

Permalink
Merge pull request #2 from 1FF/implement-cache-tags
Browse files Browse the repository at this point in the history
Implement cache tags
  • Loading branch information
t1sh0o authored Jan 31, 2019
2 parents 06e6c72 + a6fc733 commit dc93402
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 21 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "1ff/laravel-mongodb-cache",
"description": "A mongodb cache driver for laravel",
"type": "library",
"version": "2.8",
"version": "2.9",
"require": {
"jenssegers/mongodb": "3.*",
"illuminate/cache": "5.*"
Expand Down
13 changes: 3 additions & 10 deletions src/Console/Commands/MongodbCacheDropindex.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ class MongodbCacheDropIndex extends Command
*
* @var string
*/
protected $signature = 'mongodb:cache:dropindex';
protected $signature = 'mongodb:cache:dropindex {index}';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Drop indexes from the mongodb `cache` collection';
protected $description = 'Drops the passed index from the mongodb `cache` collection';

/**
* Execute the console command.
Expand All @@ -37,14 +37,7 @@ public function handle()

DB::connection('mongodb')->getMongoDB()->command([
'dropIndexes' => $cacheCollectionName,
'index' => 'key_1'
], [
'readPreference' => new ReadPreference(ReadPreference::RP_PRIMARY)
]);

DB::connection('mongodb')->getMongoDB()->command([
'dropIndexes' => $cacheCollectionName,
'index' => 'expiration_ttl_1'
'index' => $this->argument('index'),
], [
'readPreference' => new ReadPreference(ReadPreference::RP_PRIMARY)
]);
Expand Down
51 changes: 51 additions & 0 deletions src/Console/Commands/MongodbCacheIndexTags.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace ForFit\Mongodb\Cache\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use \MongoDB\Driver\ReadPreference;

/**
* Create indexes for the cache collection
*/
class MongodbCacheIndexTags extends Command
{

/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'mongodb:cache:index_tags';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Create indexes on the tags column of mongodb `cache` collection';

/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$cacheCollectionName = config('cache')['stores']['mongodb']['table'];

DB::connection('mongodb')->getMongoDB()->command([
'createIndexes' => $cacheCollectionName,
'indexes' => [
[
'key' => ['tags' => 1],
'name' => 'tags_1',
'background' => true
],
]
], [
'readPreference' => new ReadPreference(ReadPreference::RP_PRIMARY)
]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public function up()
*/
public function down()
{
Artisan::call('mongodb:cache:dropindex');
Artisan::call('mongodb:cache:dropindex', ['index' => 'key_1']);
Artisan::call('mongodb:cache:dropindex', ['index' => 'expiration_ttl_1']);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Artisan;

class AddIndexToTagsColumn extends Migration
{

/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Artisan::call('mongodb:cache:index_tags');
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Artisan::call('mongodb:cache:dropindex', ['index' => 'tags']);
}
}
68 changes: 68 additions & 0 deletions src/MongoTaggedCache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace ForFit\Mongodb\Cache;

use Illuminate\Cache\Repository;
use Illuminate\Contracts\Cache\Store;
use Illuminate\Cache\Events\KeyWritten;

class MongoTaggedCache extends Repository
{
protected $tags;

/**
* @param \Illuminate\Contracts\Cache\Store $store
* @param array $tags
*/
public function __construct(Store $store, array $tags = [])
{
parent::__construct($store);

$this->tags = $tags;
}

/**
* Store an item in the cache.
*
* @param string $key
* @param mixed $value
* @param \DateTimeInterface|\DateInterval|float|int $minutes
* @return void
*/
public function put($key, $value, $minutes = null)
{
if (is_array($key)) {
return $this->putMany($key, $value);
}

if (! is_null($minutes = $this->getMinutes($minutes))) {
$this->store->put($this->itemKey($key), $value, $minutes, $this->tags);

$this->event(new KeyWritten($key, $value, $minutes));
}
}

/**
* Saves array of key value pairs to the cache
*
* @param array $values
* @param \DateTimeInterface|\DateInterval|float|int $minutes
* @return void
*/
public function putMany(array $values, $minutes)
{
foreach ($values as $key => $value) {
$this->put($key, $value, $minutes);
}
}

/**
* Flushes the cache for the given tags
*
* @return void
*/
public function flush()
{
return $this->store->flushByTags($this->tags);
}
}
2 changes: 2 additions & 0 deletions src/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace ForFit\Mongodb\Cache;

use ForFit\Mongodb\Cache\Console\Commands\MongodbCacheIndex;
use ForFit\Mongodb\Cache\Console\Commands\MongodbCacheIndexTags;
use ForFit\Mongodb\Cache\Console\Commands\MongodbCacheDropIndex;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\ServiceProvider as ParentServiceProvider;
Expand Down Expand Up @@ -34,6 +35,7 @@ public function boot()

$this->commands([
MongodbCacheIndex::class,
MongodbCacheIndexTags::class,
MongodbCacheDropIndex::class,
]);
}
Expand Down
34 changes: 25 additions & 9 deletions src/Store.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@

class Store extends DatabaseStore
{
/**
* Sets the tags to be used
*
* @param array $tags
* @return MongoTaggedCache
*/
public function tags(array $tags)
{
return new MongoTaggedCache($this, $tags);
}

/**
* Retrieve an item from the cache by key.
Expand All @@ -29,15 +39,21 @@ public function get($key)
* @param string $key
* @param mixed $value
* @param float|int $minutes
* @param array|null $tags
* @return bool
*/
public function put($key, $value, $minutes)
public function put($key, $value, $minutes, $tags = [])
{
$expiration = ($this->getTime() + (int) ($minutes * 60)) * 1000;

try {
return (bool) $this->table()->where('key', $this->getKeyWithPrefix($key))->update(
['value' => $this->encodeForSave($value), 'expiration' => new UTCDateTime($expiration)], ['upsert' => true]
[
'value' => $this->encodeForSave($value),
'expiration' => new UTCDateTime($expiration),
'tags' => $tags
],
['upsert' => true]
);
} catch (BulkWriteException $exception) {
// high concurrency exception
Expand Down Expand Up @@ -127,15 +143,15 @@ protected function decodeFromSaved($data)
}

/**
* Forget all cache records that match the regex
* Deletes all records with the given tag
*
* @param string $key
* @return boolean
* @param array $tags
* @return void
*/
public function forgetLike($key)
public function flushByTags(array $tags)
{
$this->table()->where('key', 'like', $this->getPrefix() . '%' . $key . '%')->delete();

return true;
foreach ($tags as $tag) {
$this->table()->where('tags', $tag)->delete();
}
}
}

0 comments on commit dc93402

Please sign in to comment.