private $skewCacheTTL;
/** @var integer */
private $timeout;
- /** @var string */
- private $directoryHash;
/**
* @param array $params Parameter map:
'encoding' => 'JSON',
'cacheTTL' => 10,
'skewTTL' => 1,
- 'timeout' => 10
+ 'timeout' => 2
];
$this->host = $params['host'];
$this->protocol = $params['protocol'];
$this->directory = trim( $params['directory'], '/' );
- $this->directoryHash = sha1( $this->directory );
$this->encoding = $params['encoding'];
$this->skewCacheTTL = $params['skewTTL'];
$this->baseCacheTTL = max( $params['cacheTTL'] - $this->skewCacheTTL, 0 );
$this->timeout = $params['timeout'];
if ( !isset( $params['cache'] ) ) {
- $this->srvCache = new HashBagOStuff( [] );
+ $this->srvCache = new HashBagOStuff();
} elseif ( $params['cache'] instanceof BagOStuff ) {
$this->srvCache = $params['cache'];
} else {
return $this->procCache['config'][$name];
}
+ /**
+ * @throws ConfigException
+ */
private function load() {
if ( $this->procCache !== null ) {
return; // already loaded
}
$now = microtime( true );
- $key = $this->srvCache->makeKey( 'variable', $this->directoryHash );
+ $key = $this->srvCache->makeGlobalKey(
+ __CLASS__,
+ $this->host,
+ $this->directory
+ );
// Get the cached value or block until it is regenerated (by this or another thread)...
$data = null; // latest config info
if ( $this->srvCache->lock( $key, 0, $this->baseCacheTTL ) ) {
try {
list( $config, $error, $retry ) = $this->fetchAllFromEtcd();
- if ( $config === null ) {
- $this->logger->error( "Failed to fetch configuration: $error" );
- // Fail fast if the error is likely to just keep happening
- return $retry
- ? WaitConditionLoop::CONDITION_CONTINUE
- : WaitConditionLoop::CONDITION_FAILED;
- }
-
- // Avoid having all servers expire cache keys at the same time
- $expiry = microtime( true ) + $this->baseCacheTTL;
- $expiry += mt_rand( 0, 1e6 ) / 1e6 * $this->skewCacheTTL;
+ if ( is_array( $config ) ) {
+ // Avoid having all servers expire cache keys at the same time
+ $expiry = microtime( true ) + $this->baseCacheTTL;
+ $expiry += mt_rand( 0, 1e6 ) / 1e6 * $this->skewCacheTTL;
- $data = [ 'config' => $config, 'expires' => $expiry ];
- $this->srvCache->set( $key, $data, BagOStuff::TTL_INDEFINITE );
+ $data = [ 'config' => $config, 'expires' => $expiry ];
+ $this->srvCache->set( $key, $data, BagOStuff::TTL_INDEFINITE );
- $this->logger->info( "Refreshed stale etcd configuration cache." );
+ $this->logger->info( "Refreshed stale etcd configuration cache." );
- return WaitConditionLoop::CONDITION_REACHED;
+ return WaitConditionLoop::CONDITION_REACHED;
+ } else {
+ $this->logger->error( "Failed to fetch configuration: $error" );
+ if ( !$retry ) {
+ // Fail fast since the error is likely to keep happening
+ return WaitConditionLoop::CONDITION_FAILED;
+ }
+ }
} finally {
$this->srvCache->unlock( $key ); // release mutex
}
}
// Avoid the server next time if that failed
- $dsd->removeServer( $server, $servers );
+ $servers = $dsd->removeServer( $server, $servers );
} while ( $servers );
return [ $config, $error, $retry ];
$name = basename( $node['key'] );
$value = $this->unserialize( $node['value'] );
- if ( !is_array( $value ) || !isset( $value['val'] ) ) {
+ if ( !is_array( $value ) || !array_key_exists( 'val', $value ) ) {
return [ null, "Failed to parse value for '$name'.", false ];
}