Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,4 @@ script:
- composer test -- --coverage-clover=build/logs/clover.xml

after_success:
- composer require satooshi/php-coveralls
- vendor/bin/coveralls -v
- bash <(curl -s https://codecov.io/bash)
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,8 @@ Porter is published under the open source GNU Lesser General Public License v3.0
[Downloads image]: https://poser.pugx.org/scriptfusion/porter/downloads "Total downloads"
[Build]: http://travis-ci.org/ScriptFUSION/Porter
[Build image]: https://travis-ci.org/ScriptFUSION/Porter.svg?branch=master "Build status"
[Coverage]: https://coveralls.io/github/ScriptFUSION/Porter
[Coverage image]: https://coveralls.io/repos/ScriptFUSION/Porter/badge.svg "Test coverage"
[Coverage]: https://codecov.io/gh/ScriptFUSION/Porter
[Coverage image]: https://codecov.io/gh/ScriptFUSION/Porter/branch/master/graphs/badge.svg "Test coverage"
[Style]: https://styleci.io/repos/49824895
[Style image]: https://styleci.io/repos/49824895/shield?style=flat "Code style"

Expand Down
15 changes: 15 additions & 0 deletions src/Cache/Cache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
namespace ScriptFUSION\Porter\Cache;

/**
* Defines caching methods.
*/
interface Cache
{
/**
* Gets a value indicating whether the cache is available for read or write access.
*
* @return bool True if cache is available, otherwise false.
*/
public function isCacheAvailable();
}
29 changes: 0 additions & 29 deletions src/Cache/CacheToggle.php

This file was deleted.

9 changes: 7 additions & 2 deletions src/Cache/CacheUnavailableException.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@
*/
class CacheUnavailableException extends \RuntimeException implements CacheException
{
public static function modify()
public static function unsupported()
{
return new self('Cannot modify cache: cache unavailable.');
return new self('Cannot cache: connector does not support caching.');
}

public static function unavailable()
{
return new self('Cannot cache: connector reported cache currently unavailable.');
}
}
34 changes: 10 additions & 24 deletions src/Connector/CachingConnector.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
namespace ScriptFUSION\Porter\Connector;

use Psr\Cache\CacheItemPoolInterface;
use ScriptFUSION\Porter\Cache\Cache;
use ScriptFUSION\Porter\Cache\CacheKeyGenerator;
use ScriptFUSION\Porter\Cache\CacheToggle;
use ScriptFUSION\Porter\Cache\InvalidCacheKeyException;
use ScriptFUSION\Porter\Cache\JsonCacheKeyGenerator;
use ScriptFUSION\Porter\Cache\MemoryCache;
Expand All @@ -12,7 +12,7 @@
/**
* Caches remote data using PSR-6-compliant objects.
*/
abstract class CachingConnector implements Connector, CacheToggle
abstract class CachingConnector implements Connector, Cache
{
const RESERVED_CHARACTERS = '{}()/\@:';

Expand All @@ -21,11 +21,6 @@ abstract class CachingConnector implements Connector, CacheToggle
*/
private $cache;

/**
* @var bool
*/
private $cacheEnabled = true;

/**
* @var CacheKeyGenerator
*/
Expand All @@ -38,16 +33,17 @@ public function __construct(CacheItemPoolInterface $cache = null, CacheKeyGenera
}

/**
* @param ConnectionContext $context
* @param string $source
* @param EncapsulatedOptions|null $options
*
* @return mixed
*
* @throws InvalidCacheKeyException
*/
public function fetch($source, EncapsulatedOptions $options = null)
public function fetch(ConnectionContext $context, $source, EncapsulatedOptions $options = null)
{
if ($this->isCacheEnabled()) {
if ($context->shouldCache()) {
$optionsCopy = $options ? $options->copy() : [];

ksort($optionsCopy);
Expand All @@ -68,6 +64,11 @@ public function fetch($source, EncapsulatedOptions $options = null)

abstract public function fetchFreshData($source, EncapsulatedOptions $options = null);

public function isCacheAvailable()
{
return true;
}

public function getCache()
{
return $this->cache;
Expand All @@ -78,21 +79,6 @@ public function setCache(CacheItemPoolInterface $cache)
$this->cache = $cache;
}

public function enableCache()
{
$this->cacheEnabled = true;
}

public function disableCache()
{
$this->cacheEnabled = false;
}

public function isCacheEnabled()
{
return $this->cacheEnabled;
}

public function getCacheKeyGenerator()
{
return $this->cacheKeyGenerator;
Expand Down
56 changes: 56 additions & 0 deletions src/Connector/ConnectionContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php
namespace ScriptFUSION\Porter\Connector;

use ScriptFUSION\Porter\Cache\CacheAdvice;

final class ConnectionContext
{
private $cacheAdvice;

private $fetchExceptionHandler;

private $maxFetchAttempts;

public function __construct(CacheAdvice $cacheAdvice, callable $fetchExceptionHandler, $maxFetchAttempts)
{
$this->cacheAdvice = $cacheAdvice;
$this->fetchExceptionHandler = $fetchExceptionHandler;
$this->maxFetchAttempts = (int)$maxFetchAttempts;
}

public function retry(callable $callable)
{
return \ScriptFUSION\Retry\retry(
$this->maxFetchAttempts,
$callable,
function (\Exception $exception) {
// Throw exception if unrecoverable.
if (!$exception instanceof RecoverableConnectorException) {
throw $exception;
}

call_user_func($this->fetchExceptionHandler, $exception);
}
);
}

/**
* Gets a value indicating whether a connector should cache data.
*
* @return bool True if the connector should cache data, otherwise false.
*/
public function shouldCache()
{
return $this->cacheAdvice->anyOf(CacheAdvice::SHOULD_CACHE(), CacheAdvice::MUST_CACHE());
}

/**
* Gets a value indicating whether a connector must support caching.
*
* @return bool True if connector must support caching, otherwise false.
*/
public function mustSupportCaching()
{
return $this->cacheAdvice->anyOf(CacheAdvice::MUST_CACHE(), CacheAdvice::MUST_NOT_CACHE());
}
}
19 changes: 19 additions & 0 deletions src/Connector/ConnectionContextFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
namespace ScriptFUSION\Porter\Connector;

use ScriptFUSION\Porter\Specification\ImportSpecification;
use ScriptFUSION\StaticClass;

final class ConnectionContextFactory
{
use StaticClass;

public static function create(ImportSpecification $specification)
{
return new ConnectionContext(
$specification->getCacheAdvice(),
$specification->getFetchExceptionHandler(),
$specification->getMaxFetchAttempts()
);
}
}
3 changes: 2 additions & 1 deletion src/Connector/Connector.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ interface Connector
* Fetches data from the specified source optionally augmented by the
* specified options.
*
* @param ConnectionContext $context TODO.
* @param string $source Source.
* @param EncapsulatedOptions $options Optional. Options.
*
* @return mixed Data.
*/
public function fetch($source, EncapsulatedOptions $options = null);
public function fetch(ConnectionContext $context, $source, EncapsulatedOptions $options = null);
}
2 changes: 1 addition & 1 deletion src/Connector/NullConnector.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

class NullConnector implements Connector
{
public function fetch($source, EncapsulatedOptions $options = null)
public function fetch(ConnectionContext $context, $source, EncapsulatedOptions $options = null)
{
// Intentionally empty.
}
Expand Down
39 changes: 39 additions & 0 deletions src/Connector/SuperConnector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
namespace ScriptFUSION\Porter\Connector;

use ScriptFUSION\Porter\Cache\Cache;
use ScriptFUSION\Porter\Cache\CacheUnavailableException;
use ScriptFUSION\Porter\Options\EncapsulatedOptions;

final class SuperConnector
{
private $connector;

private $context;

public function __construct(Connector $connector, ConnectionContext $context)
{
$this->connector = $connector;
$this->context = $context;
}

public function fetch($source, EncapsulatedOptions $options = null)
{
$this->validateCacheState();

return $this->connector->fetch($this->context, $source, $options);
}

private function validateCacheState()
{
if ($this->context->mustSupportCaching()) {
if (!$this->connector instanceof Cache) {
throw CacheUnavailableException::unsupported();
}

if (!$this->connector->isCacheAvailable()) {
throw CacheUnavailableException::unavailable();
}
}
}
}
Loading