You are here

class StatsTracker in Purge 8.3

Provides the queue statistics tracker.

Hierarchy

Expanded class hierarchy of StatsTracker

1 string reference to 'StatsTracker'
purge.services.yml in ./purge.services.yml
purge.services.yml
1 service uses StatsTracker
purge.queue.stats in ./purge.services.yml
Drupal\purge\Plugin\Purge\Queue\StatsTracker

File

src/Plugin/Purge/Queue/StatsTracker.php, line 11

Namespace

Drupal\purge\Plugin\Purge\Queue
View source
class StatsTracker implements StatsTrackerInterface {

  /**
   * Loaded statistical counters.
   *
   * @var \Drupal\purge\Counter\CounterInterface[]
   */
  protected $instances = [];

  /**
   * Current iterator position.
   *
   * @var int
   *
   * @ingroup iterator
   */
  protected $position = 0;

  /**
   * The state key value store.
   *
   * @var \Drupal\Core\State\StateInterface
   */
  protected $state;

  /**
   * Buffer of counter values that need to be written back to state storage.
   *
   * @var float[]
   */
  protected $stateBuffer = [];

  /**
   * Mapping of classes used for each counter.
   *
   * @var string[]
   */
  protected $statClasses = [
    self::NUMBER_OF_ITEMS => NumberOfItemsStatistic::class,
    self::TOTAL_PROCESSING => TotalProcessingStatistic::class,
    self::TOTAL_SUCCEEDED => TotalSucceededStatistic::class,
    self::TOTAL_FAILED => TotalFailedStatistic::class,
    self::TOTAL_NOT_SUPPORTED => TotalNotSupportedStatistic::class,
  ];

  /**
   * Non-associative but keyed layout of the statistical counters loaded.
   *
   * @var string[]
   */
  protected $stats = [
    self::NUMBER_OF_ITEMS => 'purge_queue_number_of_items',
    self::TOTAL_PROCESSING => 'purge_queue_total_processing',
    self::TOTAL_SUCCEEDED => 'purge_queue_total_succeeded',
    self::TOTAL_FAILED => 'purge_queue_total_failed',
    self::TOTAL_NOT_SUPPORTED => 'purge_queue_total_not_supported',
  ];

  /**
   * Construct a statistics tracker.
   *
   * @param \Drupal\Core\State\StateInterface $state
   *   The state key value store.
   */
  public function __construct(StateInterface $state) {
    $this->state = $state;
  }

  /**
   * Initialize the counter instances.
   */
  protected function initializeStatistics() {
    if (!empty($this->instances)) {
      return;
    }

    // Fetch all statistic values from the state API at once.
    $values = $this->state
      ->getMultiple($this->stats);

    // Instantiate the persistent counters with the given values.
    foreach ($this->stats as $i => $statekey) {

      // Set a default as CounterInterface only understands integers.
      if (!isset($values[$statekey]) || is_null($values[$statekey])) {
        $values[$statekey] = 0;
      }

      // Instantiate the counter and pass a write callback that puts written
      // values directly back into $this->stateBuffer. At the end of this
      // request, ::destruct() will pick them up and save the values.
      $this->instances[$i] = new $this->statClasses[$i]($values[$statekey]);
      $this->instances[$i]
        ->setWriteCallback(function ($value) use ($statekey) {
        $this->stateBuffer[$statekey] = $value;
      });
    }
  }

  /**
   * {@inheritdoc}
   *
   * @ingroup countable
   */
  public function count() {
    $this
      ->initializeStatistics();
    return count($this->instances);
  }

  /**
   * {@inheritdoc}
   */
  public function numberOfItems() {
    $this
      ->initializeStatistics();
    return $this->instances[self::NUMBER_OF_ITEMS];
  }

  /**
   * {@inheritdoc}
   */
  public function totalFailed() {
    $this
      ->initializeStatistics();
    return $this->instances[self::TOTAL_FAILED];
  }

  /**
   * {@inheritdoc}
   */
  public function totalProcessing() {
    $this
      ->initializeStatistics();
    return $this->instances[self::TOTAL_PROCESSING];
  }

  /**
   * {@inheritdoc}
   */
  public function totalSucceeded() {
    $this
      ->initializeStatistics();
    return $this->instances[self::TOTAL_SUCCEEDED];
  }

  /**
   * {@inheritdoc}
   */
  public function totalNotSupported() {
    $this
      ->initializeStatistics();
    return $this->instances[self::TOTAL_NOT_SUPPORTED];
  }

  /**
   * {@inheritdoc}
   */
  public function destruct() {

    // When the buffer contains changes, write them to the state API in one go.
    if (count($this->stateBuffer)) {
      $this->state
        ->setMultiple($this->stateBuffer);
      $this->stateBuffer = [];
    }
  }

  /**
   * {@inheritdoc}
   */
  public function resetTotals() {
    $this
      ->totalFailed()
      ->set(0);
    $this
      ->totalProcessing()
      ->set(0);
    $this
      ->totalSucceeded()
      ->set(0);
    $this
      ->totalNotSupported()
      ->set(0);
  }

  /**
   * {@inheritdoc}
   */
  public function updateTotals(array $invalidations) {
    $changes = [
      'totalProcessing' => 0,
      'totalSucceeded' => 0,
      'totalFailed' => 0,
      'totalNotSupported' => 0,
    ];
    foreach ($invalidations as $invalidation) {
      if ($invalidation
        ->getState() === InvStatesInterface::PROCESSING) {
        $changes['totalProcessing']++;
      }
      elseif ($invalidation
        ->getState() === InvStatesInterface::SUCCEEDED) {
        $changes['totalSucceeded']++;
      }
      elseif ($invalidation
        ->getState() === InvStatesInterface::FAILED) {
        $changes['totalFailed']++;
      }
      elseif ($invalidation
        ->getState() === InvStatesInterface::NOT_SUPPORTED) {
        $changes['totalNotSupported']++;
      }
    }
    foreach ($changes as $stat => $value) {
      if ($value === 0) {
        continue;
      }
      elseif ($value > 0) {
        $this
          ->{$stat}()
          ->increment($value);
      }
      elseif ($value < 0) {
        $this
          ->{$stat}()
          ->decrement(abs($value));
      }
    }
  }

  /**
   * Return the current element.
   *
   * @ingroup iterator
   */
  public function current() {
    $this
      ->initializeStatistics();
    if ($this
      ->valid()) {
      return $this->instances[$this->position];
    }
    return FALSE;
  }

  /**
   * Return the key of the current element.
   *
   * @ingroup iterator
   */
  public function key() {
    $this
      ->initializeStatistics();
    return $this->position;
  }

  /**
   * Move forward to next element.
   *
   * @ingroup iterator
   */
  public function next() {
    $this
      ->initializeStatistics();
    ++$this->position;
  }

  /**
   * Rewind the Iterator to the first element.
   *
   * @ingroup iterator
   */
  public function rewind() {
    $this->position = 0;
  }

  /**
   * Checks if current position is valid.
   *
   * @ingroup iterator
   */
  public function valid() {
    $this
      ->initializeStatistics();
    return isset($this->instances[$this->position]);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
StatsTracker::$instances protected property Loaded statistical counters.
StatsTracker::$position protected property Current iterator position.
StatsTracker::$statClasses protected property Mapping of classes used for each counter.
StatsTracker::$state protected property The state key value store.
StatsTracker::$stateBuffer protected property Buffer of counter values that need to be written back to state storage.
StatsTracker::$stats protected property Non-associative but keyed layout of the statistical counters loaded.
StatsTracker::count public function
StatsTracker::current public function Return the current element.
StatsTracker::destruct public function Performs destruct operations. Overrides DestructableInterface::destruct
StatsTracker::initializeStatistics protected function Initialize the counter instances.
StatsTracker::key public function Return the key of the current element.
StatsTracker::next public function Move forward to next element.
StatsTracker::numberOfItems public function The number of items currently in the queue. Overrides StatsTrackerInterface::numberOfItems
StatsTracker::resetTotals public function Reset the total counters. Overrides StatsTrackerInterface::resetTotals
StatsTracker::rewind public function Rewind the Iterator to the first element.
StatsTracker::totalFailed public function Total number of failed queue items. Overrides StatsTrackerInterface::totalFailed
StatsTracker::totalNotSupported public function Total number of not supported invalidations. Overrides StatsTrackerInterface::totalNotSupported
StatsTracker::totalProcessing public function Total number of multi-step cache invalidations. Overrides StatsTrackerInterface::totalProcessing
StatsTracker::totalSucceeded public function Total number of succeeded queue items. Overrides StatsTrackerInterface::totalSucceeded
StatsTracker::updateTotals public function Automatically update the total counters for the given invalidations. Overrides StatsTrackerInterface::updateTotals
StatsTracker::valid public function Checks if current position is valid.
StatsTracker::__construct public function Construct a statistics tracker.
StatsTrackerInterface::NUMBER_OF_ITEMS constant Array index for ::numberOfItems().
StatsTrackerInterface::TOTAL_FAILED constant Array index for ::totalFailed().
StatsTrackerInterface::TOTAL_NOT_SUPPORTED constant Array index for ::totalNotSupported().
StatsTrackerInterface::TOTAL_PROCESSING constant Array index for ::totalProcessing().
StatsTrackerInterface::TOTAL_SUCCEEDED constant Array index for ::totalSucceeded().