Skip to content

Commit

Permalink
Allow to use multiple memcached servers for caching
Browse files Browse the repository at this point in the history
  • Loading branch information
JustBlackBird committed Mar 24, 2015
1 parent b18aef4 commit 31b0957
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 8 deletions.
9 changes: 7 additions & 2 deletions src/mibew/configs/default_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,13 @@ cache:

# The lines below represents default Memcached server configurations. They
# will be used only if the "storage" option is set to "memcached".
memcached_host: localhost
memcached_port: 11211
memcached_servers:
- host: localhost
port: 11211
# The "weight" field is optional and can be omitted.
weight: 0
# Actually, one can use any number of memcached servers he wants. Just
# add servers description like the one above.

# Locales
## Native name will be used in this locale
Expand Down
67 changes: 61 additions & 6 deletions src/mibew/libs/classes/Mibew/Cache/CacheFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@ public function setOptions($options)
$defaults = array(
'storage' => 'file_system',
'path' => '/tmp',
'memcached_host' => 'localhost',
'memcached_port' => 11211,
'memcached_servers' => array(),
);

// Make sure all passed options are known
Expand Down Expand Up @@ -144,12 +143,26 @@ public function getCache()
$driver = new FileSystemDriver();
$driver->setOptions(array('path' => $this->getOption('path')));
} elseif ($storage === 'memcached') {
$servers = $this->getOption('memcached_servers');

// Make sure memcached servers was described correctly. The next
// statement will throw Exception if something is wrong so we do
// not need to check the result.
$this->validateMemcachedServers($servers);

// Convert structure from the "memcached_servers" option to the
// form used in cache driver.
$formated_servers = array_map(function ($server) {
return array(
$server['host'],
intval($server['port']),
isset($server['weight']) ? intval($server['weight']) : 0,
);
}, $servers);

$driver = new MemcacheDriver();
$driver->setOptions(array(
'servers' => array(
$this->getOption('memcached_host'),
$this->getOption('memcached_port'),
),
'servers' => $formated_servers,
// Use only PHP's "memcached" extension.
'extension' => 'memcached'
));
Expand All @@ -165,4 +178,46 @@ public function getCache()

return $this->cache;
}

/**
* Checks if the specified array is a valid memcached servers array.
*
* @param Array $servers
* @throws \UnexpectedValueException
*/
private function validateMemcachedServers($servers)
{
foreach ($servers as $server) {
// The host should be specified.
if (!isset($server['host']) || !$server['host']) {
throw new \UnexpectedValueException('Memcached server port was not specified.');
}

// The port can be only a positive integer.
$correct_port = isset($server['port'])
&& (bool)filter_var($server['port'], FILTER_VALIDATE_INT)
&& intval($server['port']) > 0;
if (!$correct_port) {
throw new \UnexpectedValueException(sprintf(
'Memcached server port can be only a positive integer. "%s" is given.',
isset($server['port']) ? $server['port'] : ''
));
}

if (!isset($server['weight'])) {
// The weight is optional thus it can be missed.
continue;
}

// The weight can be only a positive integer if specified.
$correct_weight = (bool)filter_var($server['weight'], FILTER_VALIDATE_INT)
&& intval($server['weight']) > 0;
if (!$correct_weight) {
throw new \UnexpectedValueException(sprintf(
'Memcached server weight can be only a positive integer. "%s" is given.',
$server['weight']
));
}
}
}
}

0 comments on commit 31b0957

Please sign in to comment.