X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Flibs%2Fobjectcache%2FRESTBagOStuff.php;h=c127ec6910fd69ee9597395440c7c6d212a7edf0;hb=b8e0ca16aa743581f5fac5cef8bed5ac2bf6e7cb;hp=d3aa9f5cb17d1b3e6d3db69aca2db263d98047c5;hpb=be80e2614cfd0dd56eda32edb93d368aee58a729;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/libs/objectcache/RESTBagOStuff.php b/includes/libs/objectcache/RESTBagOStuff.php index d3aa9f5cb1..c127ec6910 100644 --- a/includes/libs/objectcache/RESTBagOStuff.php +++ b/includes/libs/objectcache/RESTBagOStuff.php @@ -1,5 +1,7 @@ client = new MultiHttpClient( [] ); + // Pass through some params to the HTTP client. + $clientParams = [ + 'connTimeout' => $params['connTimeout'] ?? self::DEFAULT_CONN_TIMEOUT, + 'reqTimeout' => $params['reqTimeout'] ?? self::DEFAULT_REQ_TIMEOUT, + ]; + foreach ( [ 'caBundlePath', 'proxy' ] as $key ) { + if ( isset( $params[$key] ) ) { + $clientParams[$key] = $params[$key]; + } + } + $this->client = new MultiHttpClient( $clientParams ); } else { $this->client = $params['client']; } + // The parent constructor calls setLogger() which sets the logger in $this->client + parent::__construct( $params ); // Make sure URL ends with / $this->url = rtrim( $params['url'], '/' ) . '/'; // Default config, R+W > N; no locks on reads though; writes go straight to state-machine $this->attrMap[self::ATTR_SYNCWRITES] = self::QOS_SYNCWRITES_QC; } + public function setLogger( LoggerInterface $logger ) { + parent::setLogger( $logger ); + $this->client->setLogger( $logger ); + } + /** * @param string $key * @param int $flags Bitfield of BagOStuff::READ_* constants [optional] @@ -95,43 +124,52 @@ class RESTBagOStuff extends BagOStuff { return false; } - /** - * Set an item - * - * @param string $key - * @param mixed $value - * @param int $exptime Either an interval in seconds or a unix timestamp for expiry - * @param int $flags Bitfield of BagOStuff::WRITE_* constants - * @return bool Success - */ public function set( $key, $value, $exptime = 0, $flags = 0 ) { + // @TODO: respect WRITE_SYNC (e.g. EACH_QUORUM) + // @TODO: respect $exptime $req = [ 'method' => 'PUT', 'url' => $this->url . rawurlencode( $key ), 'body' => serialize( $value ) ]; list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->client->run( $req ); - if ( $rcode === 200 || $rcode === 201 ) { + if ( $rcode === 200 || $rcode === 201 || $rcode === 204 ) { return true; } return $this->handleError( "Failed to store $key", $rcode, $rerr ); } - /** - * Delete an item. - * - * @param string $key - * @return bool True if the item was deleted or not found, false on failure - */ - public function delete( $key ) { + public function add( $key, $value, $exptime = 0, $flags = 0 ) { + // @TODO: make this atomic + if ( $this->get( $key ) === false ) { + return $this->set( $key, $value, $exptime, $flags ); + } + + return false; // key already set + } + + public function delete( $key, $flags = 0 ) { + // @TODO: respect WRITE_SYNC (e.g. EACH_QUORUM) $req = [ 'method' => 'DELETE', 'url' => $this->url . rawurlencode( $key ), ]; list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->client->run( $req ); - if ( $rcode === 200 || $rcode === 204 || $rcode === 205 ) { + if ( in_array( $rcode, [ 200, 204, 205, 404, 410 ] ) ) { return true; } return $this->handleError( "Failed to delete $key", $rcode, $rerr ); } + + public function incr( $key, $value = 1 ) { + // @TODO: make this atomic + $n = $this->get( $key, self::READ_LATEST ); + if ( $this->isInteger( $n ) ) { // key exists? + $n = max( $n + intval( $value ), 0 ); + // @TODO: respect $exptime + return $this->set( $key, $n ) ? $n : false; + } + + return false; + } }