Skip to content

Commit

Permalink
Merge pull request #24 from square/any-simple-cache
Browse files Browse the repository at this point in the history
Drop PSR SimpleCache
  • Loading branch information
khepin authored Jan 10, 2024
2 parents 0750f3a + f055a76 commit 26ec47f
Show file tree
Hide file tree
Showing 14 changed files with 322 additions and 349 deletions.
22 changes: 15 additions & 7 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,15 @@ jobs:
build:
container: ubuntu:latest
runs-on: ubuntu-latest


strategy:
fail-fast: true
matrix:
php: ['8.0', '8.1', '8.2']
psr: ['2.0', '3.0']

name: 'PHP ${{ matrix.php }} - Simple Cache: ${{matrix.psr}}'

services:
redis:
image: redis:latest
Expand All @@ -22,16 +30,16 @@ jobs:

steps:
- uses: actions/checkout@v3

- name: Setup PHP with PECL extension
uses: shivammathur/setup-php@v2
with:
php-version: '7.4'
php-version: '${{ matrix.php }}'
extensions: memcached, redis

#- name: Setup Memcache
# uses: niden/actions-memcached@v7

#- name: Setup Redis
# uses: zhulik/[email protected]

Expand All @@ -48,13 +56,13 @@ jobs:
${{ runner.os }}-php-
- name: Install dependencies
run: composer install --prefer-dist --no-progress
run: composer update --with='psr/simple-cache:${{matrix.psr}}' --prefer-dist --no-interaction --no-progress

# Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit"
# Docs: https://getcomposer.org/doc/articles/scripts.md

- name: Run static analysis
run: ./vendor/bin/phpstan analyse src tests --level 5

- name: Run unit tests
run: ./vendor/bin/phpunit tests
10 changes: 4 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
FROM php:7.4.27-cli
RUN apt-get update && apt-get install -y libmemcached-dev zlib1g-dev \
&& pecl install memcached-3.1.5 \
&& docker-php-ext-enable memcached \
&& pecl install redis-5.3.7 \
&& docker-php-ext-enable redis
FROM php:8.2-cli
RUN apt-get update && apt-get install -y libz-dev libmemcached-dev zlib1g-dev libssl-dev
RUN pecl install memcached
RUN docker-php-ext-enable memcached
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
watch:
watchexec -e php -cr -- "make stan && make tests"
watchexec -e php -c -r -- "make stan && make tests"

watch-debug:
watchexec -e php -cr -- docker-compose exec php ./vendor/bin/phpunit --group debug
watchexec -e php -c -r -- docker-compose exec php ./vendor/bin/phpunit --group debug

stan:
vendor/bin/phpstan analyse src tests --level 5
Expand Down
6 changes: 2 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
}
],
"require": {
"php": ">=7.4",
"psr/simple-cache": "^1.0"
"php": ">=8.0"
},
"suggest": {
"ext-memcached": "Needed to use Square\\TTCache\\Store\\MemcachedStore and Square\\TTCache\\Store\\ShardedMemcachedStore implementations"
Expand All @@ -30,7 +29,6 @@
"phpunit/phpunit": "^9.5",
"psy/psysh": "^0.11.1",
"symfony/var-dumper": "^5",
"phpstan/phpstan": "^1.4",
"cache/redis-adapter": "^1.1"
"phpstan/phpstan": "^1.10"
}
}
2 changes: 0 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,3 @@ services:
command: tail -f phpunit.xml
memcached:
image: "memcached:latest"
redis:
image: "redis:latest"
7 changes: 4 additions & 3 deletions src/Store/CacheStoreException.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<?php declare(strict_types=1);
<?php

declare(strict_types=1);

namespace Square\TTCache\Store;

use Psr\SimpleCache\CacheException;
use Exception;

class CacheStoreException extends Exception implements CacheException
class CacheStoreException extends Exception
{
}
20 changes: 20 additions & 0 deletions src/Store/CacheStoreInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Square\TTCache\Store;

interface CacheStoreInterface
{
public function get(string $key, mixed $default = null): mixed;

public function set(string $key, mixed $value, int|\DateInterval $ttl = null): bool;

public function delete(string $key): bool;

public function getMultiple(iterable $keys, mixed $default = null): iterable;

public function setMultiple(iterable $values, int|\DateInterval $ttl = null): bool;

public function deleteMultiple(iterable $keys): bool;
}
40 changes: 27 additions & 13 deletions src/Store/MemcachedStore.php
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
<?php declare(strict_types=1);
<?php

declare(strict_types=1);

namespace Square\TTCache\Store;

use Psr\SimpleCache\CacheInterface;
use Memcached;

/**
* PSR Cache interface implementation of memcache.
*/
class MemcachedStore implements CacheInterface
class MemcachedStore implements CacheStoreInterface
{
protected Memcached $mc;

private const MC_SUCCESS = 0;

private const MC_NOT_FOUND = 16;

private const MC_VALID_CODES = [
Expand All @@ -25,31 +27,40 @@ public function __construct(Memcached $mc)
$this->mc = $mc;
}

protected function checkResultCode() : void
protected function checkResultCode(): void
{
if (!in_array($this->mc->getResultCode(), self::MC_VALID_CODES)) {
if (! in_array($this->mc->getResultCode(), self::MC_VALID_CODES)) {
throw new CacheStoreException('invalid MC return code', $this->mc->getResultCode());
}
}

public function get($key, $default = null)
public function get(string $key, mixed $default = null): mixed
{
$result = $this->mc->get($key);
$this->checkResultCode();

return $result;
}

public function set($key, $value, $ttl = null)
public function set(string $key, mixed $value, int|\DateInterval $ttl = null): bool
{
$result = $this->mc->set($key, $value, $ttl ?? 0);
if (is_null($ttl)) {
$ttl = 0;
}
if ($ttl instanceof \DateInterval) {
$ttl = (new \DateTime())->add($ttl)->getTimestamp() - time();
}
$result = $this->mc->set($key, $value, $ttl);
$this->checkResultCode();

return $result;
}

public function delete($key)
public function delete(string $key): bool
{
$result = $this->mc->delete($key);
$this->checkResultCode();

return $result;
}

Expand All @@ -58,28 +69,31 @@ public function clear(): bool
throw new CacheStoreException('not implemented on purpose');
}

public function getMultiple($keys, $default = null)
public function getMultiple(iterable $keys, mixed $default = null): iterable
{
$result = $this->mc->getMulti($keys);
$this->checkResultCode();

return $result;
}

public function setMultiple($values, $ttl = null)
public function setMultiple(iterable $values, int|\DateInterval $ttl = null): bool
{
$result = $this->mc->setMulti($values, $ttl ?? 0);
$this->checkResultCode();

return $result;
}

public function deleteMultiple($keys)
public function deleteMultiple(iterable $keys): bool
{
$result = $this->mc->deleteMulti($keys);
$this->checkResultCode();

return true;
}

public function has($key)
public function has(string $key): bool
{
throw new CacheStoreException('not implemented');
}
Expand Down
34 changes: 21 additions & 13 deletions src/Store/ShardedMemcachedStore.php
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
<?php declare(strict_types=1);
<?php

declare(strict_types=1);

namespace Square\TTCache\Store;

use Psr\SimpleCache\CacheInterface;
use Memcached;

/**
* PSR Cache interface implementation of memcache that needs to receive a sharding key
* and ensures all the values stored through this instance end up on the same MC server.
*/
class ShardedMemcachedStore implements CacheInterface
class ShardedMemcachedStore implements CacheStoreInterface
{
protected Memcached $mc;

protected string $shardingKey;

private const MC_SUCCESS = 0;

private const MC_NOT_FOUND = 16;

private const MC_VALID_CODES = [
Expand All @@ -28,36 +30,39 @@ public function __construct(Memcached $mc)
$this->mc = $mc;
}

public function setShardingKey(string $key) : void
public function setShardingKey(string $key): void
{
$this->shardingKey = $key;
}

protected function checkResultCode() : void
protected function checkResultCode(): void
{
if (!in_array($this->mc->getResultCode(), self::MC_VALID_CODES)) {
if (! in_array($this->mc->getResultCode(), self::MC_VALID_CODES)) {
throw new CacheStoreException('invalid MC return code', $this->mc->getResultCode());
}
}

public function get($key, $default = null)
public function get(string $key, mixed $default = null): mixed
{
$result = $this->mc->getByKey($this->shardingKey, $key);
$this->checkResultCode();

return $result;
}

public function set($key, $value, $ttl = null)
public function set(string $key, mixed $value, int|\DateInterval $ttl = null): bool
{
$result = $this->mc->setByKey($this->shardingKey, $key, $value, $ttl ?? 0);
$this->checkResultCode();

return $result;
}

public function delete($key): bool
public function delete(string $key): bool
{
$result = $this->mc->deleteByKey($this->shardingKey, $key);
$this->checkResultCode();

return $result;
}

Expand All @@ -66,28 +71,31 @@ public function clear(): bool
throw new CacheStoreException('not implemented on purpose');
}

public function getMultiple($keys, $default = null)
public function getMultiple(iterable $keys, mixed $default = null): iterable
{
$result = $this->mc->getMultiByKey($this->shardingKey, $keys);
$this->checkResultCode();

return $result;
}

public function setMultiple($values, $ttl = null)
public function setMultiple(iterable $values, int|\DateInterval $ttl = null): bool
{
$result = $this->mc->setMultiByKey($this->shardingKey, $values, $ttl ?? 0);
$this->checkResultCode();

return $result;
}

public function deleteMultiple($keys)
public function deleteMultiple(iterable $keys): bool
{
$result = $this->mc->deleteMultiByKey($this->shardingKey, $keys);
$this->checkResultCode();

return $result;
}

public function has($key)
public function has(string $key): bool
{
throw new CacheStoreException('not implemented');
}
Expand Down
Loading

0 comments on commit 26ec47f

Please sign in to comment.