twitter/finagle — pull request #44 by tsuna (2011-10-24 06:44:13+00:00)
Title: Add partial support for PHP's `memcache' client.

PHP has 2 popular clients, `memcache.so` and `memcached.so` (which isn't confusing at all, right?).

* `memcache.so is` from http://pecl.php.net/memcache
hashing code is @
http://svn.php.net/viewvc/pecl/memcache/trunk/memcache_standard_hash.c?revision=HEAD&view=markup
* `memcached.so` is from http://pecl.php.net/memcached
hashing code is @
http://bazaar.launchpad.net/~libmemcached-developers/libmemcached/trunk/view/head:/libmemcached/hash.cc

This change adds a new type of memcache client to support users of the `memcache` extension. These users can use finagle's Ruby client if they use CRC32, but that client doesn't support using any other hash function, and the PHP `memcache` extension can use FNV1a-32, see:
http://php.net/memcache.ini#ini.memcache.hash-function

Speaking of support for PHP clients, here's some info for posterity. The only notable difference between the two is that the `memcache` extension does this on the hash:

```c
hash = (hash >> 16) & 0x7fff;
```
like the Ruby client, but `memcached` doesn't.

For the `memcache` client, the standard hash strategy applies a modulo, whereas the consistent strategy uses the following algorithm (pseudo code):

```c
hash = hashfunc(key);
server = servers[hash % 1024];
if (!server && allow_failover) {
for (int i = 0; i < max_failover_attempts && i < 1024; i++) {
next_key = key + "-" + i;
hash = hashfunc(next_key);
server = servers[hash % 1024];
if (server) { // We found a healthy one.
break;
}
}
}
if (!server) {
// error.
} else {
// success: use the connection to that server.
}
```

For `memcached`, consistent hashing is done with Ketama, which is already supported in Finagle.