Skip to content

Instantly share code, notes, and snippets.

@1ma
Last active January 28, 2019 13:20
Show Gist options
  • Save 1ma/574e34e0526657dfdf3cfd7939218156 to your computer and use it in GitHub Desktop.
Save 1ma/574e34e0526657dfdf3cfd7939218156 to your computer and use it in GitHub Desktop.
Layout for an interruptible Availability Service
<?php
declare(strict_types=1);
final class AvailabilityServiceDriver
{
/**
* @var IterableAvailabilityService
*/
private $as;
/**
* @var float
*/
private $timeout;
public function __construct(IterableAvailabilityService $as, float $timeout)
{
$this->as = $as;
$this->timeout = $timeout;
}
public function doTheTing(): array
{
$results = [];
$startTime = self::currentTimeMillis();
foreach ($this->as as $availabilityDTO) {
$results[] = $availabilityDTO;
if (self::timeSince($startTime) > $this->timeout) {
break;
}
}
return $results;
}
private static function timeSince(float $startTime): float
{
return self::currentTimeMillis() - $startTime;
}
private static function currentTimeMillis(): float
{
return \microtime(true);
}
}
<?php
declare(strict_types=1);
$timeout = 1.0; // Try different values to see how count($results) vary
$driver = new AvailabilityServiceDriver(new IterableAvailabilityService(), $timeout);
$results = $driver->doTheTing();
var_dump(\count($results));
<?php
declare(strict_types=1);
final class IterableAvailabilityService implements Iterator
{
public function __construct()
{
}
/**
* This is called once at the start of the iteration (e.g. when it enters
* the foreach loop). It should make the initial DB queries.
*
* /!\ ACHTUNG rewind() MUST take care of preparing the first availability
* result. Usually the next result is computed by next(), but on the first
* iteration next() is not called.
*/
public function rewind()
{
return null;
}
/**
* This method is called on each iteration and determines whether to enter
* the body of the foreach or not.
*
* It should return true while there are still availability results to
* process, and false when all work has already been done.
*/
public function valid()
{
return true;
}
/**
* This method is called on each iteration, it returns the current availability
* result.
*/
public function current()
{
return 'dsadsa';
}
/**
* This method is called on each iteration EXCEPT the first one. It computes the
* next availability result.
*
* After preparing the last result it MUST make sure that the following call to
* valid() will return false.
*/
public function next()
{
return null;
}
/**
* Identifier of the current() availability result. Whatever. It is not important
* for our use case.
*/
public function key()
{
// Could be the ID of the current product
return 1234;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment