MatthiasMullie\Scrapbook\Scale\StampedeProtector::getMulti PHP Method

getMulti() public method

public getMulti ( array $keys, array &$tokens = null )
$keys array
$tokens array
    public function getMulti(array $keys, array &$tokens = null)
    {
        // fetch both requested keys + stampede protection indicators at once
        $stampedeKeys = array_combine($keys, array_map(array($this, 'stampedeKey'), $keys));
        $values = $this->cache->getMulti(array_merge($keys, $stampedeKeys), $tokens);
        // figure out which of the requested keys are protected, and which need
        // protection (=currently empty & not yet protected)
        $protected = array_keys(array_intersect($stampedeKeys, array_keys($values)));
        $protect = array_diff($keys, array_keys($values), $protected);
        // protect keys that we couldn't find, and remove them from the list of
        // keys we want results from, because we'll keep fetching empty keys
        // (that are currently protected)
        $done = $this->protect($protect);
        $keys = array_diff($keys, $done);
        // we may have failed to protect some keys after all (race condition
        // with another process), in which case we also have to keep polling
        // those keys (which the other process is likely working on already)
        $protected += array_diff($protect, $done);
        // we over-fetched (to include stampede indicators), now limit the
        // results to only the keys we requested
        $results = array_intersect_key($values, array_flip($keys));
        $tokens = array_intersect_key($tokens, $results);
        // we may not have been able to retrieve all keys yet: some may have
        // been "protected" (and are being regenerated in another process) in
        // which case we'll retry a couple of times, hoping the other process
        // stores the new value in the meantime
        $attempts = $this->attempts;
        while (--$attempts > 0 && !empty($protected) && $this->sleep()) {
            $values = $this->cache->getMulti($protected, $tokens2);
            $results += array_intersect_key($values, array_flip($keys));
            $tokens += array_intersect_key($tokens2, array_flip($keys));
            // don't keep polling for values we just fetched...
            $protected = array_diff($protected, array_keys($values));
        }
        return $results;
    }