public function set(string $primary_key, $sub_key, $value, int $expires_in = 0): bool
    {
        if (!$this->enabled) {
            return false; // Not possible.
        }
        $expires_in = max(0, $expires_in);
        $expires    = $expires_in ? time() + $expires_in : 0;

        if (!($key = $this->key($primary_key, $sub_key))) {
            return false; // Fail; e.g., race condition.
            //
        } elseif ($value === null || is_resource($value)) {
            throw $this->c::issue('Incompatible data type.');
        }
        do { // Avoid race issues.
            $cas      = $cas ?? 0;
            $attempts = $attempts ?? 0;
            ++$attempts; // Counter.

            $this->Pool->get($key, null, $cas);

            if ($this->Pool->getResultCode() === \Memcached::RES_NOTFOUND) {
                if ($this->Pool->add($key, $value, $expires)) {
                    return true; // All good; stop here.
                }
            } elseif ($this->Pool->cas($cas, $key, $value, $expires)) {
                return true; // All good; stop here.
            }
            $result_code = $this->Pool->getResultCode();
            //
        } while ($attempts < $this::MAX_WRITE_ATTEMPTS // Give up after X attempts.
                && ($result_code === \Memcached::RES_NOTSTORED || $result_code === \Memcached::RES_DATA_EXISTS));

        return false; // Fail; e.g., race condition or unexpected error.
    }
public function set(string $primary_key, $sub_key, $value, int $expires_in = 0): bool
    {
        if (!$this->enabled) {
            return false; // Not possible.
        }
        $expires_in = max(0, $expires_in);
        $expires    = $expires_in ? time() + $expires_in : 0;

        if (!($key = $this->key($primary_key, $sub_key))) {
            return false; // Fail; e.g., race condition.
            //
        } elseif ($value === null || is_resource($value)) {
            throw $this->c::issue('Incompatible data type.');
        }
        do { // Avoid race issues.
            $cas      = $cas ?? 0;
            $attempts = $attempts ?? 0;
            ++$attempts; // Counter.

            $this->Pool->get($key, null, $cas);

            if ($this->Pool->getResultCode() === \Memcached::RES_NOTFOUND) {
                if ($this->Pool->add($key, $value, $expires)) {
                    return true; // All good; stop here.
                }
            } elseif ($this->Pool->cas($cas, $key, $value, $expires)) {
                return true; // All good; stop here.
            }
            $result_code = $this->Pool->getResultCode();
            //
        } while ($attempts < $this::MAX_WRITE_ATTEMPTS // Give up after X attempts.
                && ($result_code === \Memcached::RES_NOTSTORED || $result_code === \Memcached::RES_DATA_EXISTS));

        return false; // Fail; e.g., race condition or unexpected error.
    }
public function set ( string $ primary_key , $ sub_key , $ value , int $ expires_in = 0 ) : bool { if ( ! $ this -> enabled ) { return false ; // Not possible. } $ expires_in = max ( 0 , $ expires_in ) ; $ expires = $ expires_in ? time ( ) + $ expires_in : 0 ; if ( ! ( $ key = $ this -> key ( $ primary_key , $ sub_key ) ) ) { return false ; // Fail; e.g., race condition. // } elseif ( $ value === null || is_resource ( $ value ) ) { throw $ this -> c :: issue ( 'Incompatible data type.' ) ; } do { // Avoid race issues. $ cas = $ cas ?? 0 ; $ attempts = $ attempts ?? 0 ; ++ $ attempts ; // Counter. $ this -> Pool -> get ( $ key , null , $ cas ) ; if ( $ this -> Pool -> getResultCode ( ) === \ Memcached :: RES_NOTFOUND ) { if ( $ this -> Pool -> add ( $ key , $ value , $ expires ) ) { return true ; // All good; stop here. } } elseif ( $ this -> Pool -> cas ( $ cas , $ key , $ value , $ expires ) ) { return true ; // All good; stop here. } $ result_code = $ this -> Pool -> getResultCode ( ) ; // } while ( $ attempts < $ this :: MAX_WRITE_ATTEMPTS // Give up after X attempts. && ( $ result_code === \ Memcached :: RES_NOTSTORED || $ result_code === \ Memcached :: RES_DATA_EXISTS ) ) ; return false ; // Fail; e.g., race condition or unexpected error. }
Set|update cache key.

@since 151216 Memcache utils.

@param string     $primary_key Primary key.
@param string|int $sub_key     Sub-key to set.
@param string     $value       Value to cache (1MB max).
@param int        $expires_in  Expires (in seconds).

@return bool True on success.
Set|update cache key .