Multiple servers and failover support

Automatic compress threshold
+3 new methods: memcache->addServer(), getExtendedStats(), setCompressThreshold()
This commit is contained in:
Mikael Johansson
2005-10-29 14:24:50 +00:00
parent f01af9070d
commit edc0feab2c
15 changed files with 1510 additions and 722 deletions

View File

@@ -1 +1 @@
Antony Dovgal
Antony Dovgal, Mikael Johansson

1763
memcache.c

File diff suppressed because it is too large Load Diff

View File

@@ -42,6 +42,7 @@ PHP_MINFO_FUNCTION(memcache);
PHP_FUNCTION(memcache_connect);
PHP_FUNCTION(memcache_pconnect);
PHP_FUNCTION(memcache_add_server);
PHP_FUNCTION(memcache_get_version);
PHP_FUNCTION(memcache_add);
PHP_FUNCTION(memcache_set);
@@ -50,6 +51,8 @@ PHP_FUNCTION(memcache_get);
PHP_FUNCTION(memcache_delete);
PHP_FUNCTION(memcache_debug);
PHP_FUNCTION(memcache_get_stats);
PHP_FUNCTION(memcache_get_extended_stats);
PHP_FUNCTION(memcache_set_compress_threshold);
PHP_FUNCTION(memcache_increment);
PHP_FUNCTION(memcache_decrement);
PHP_FUNCTION(memcache_close);
@@ -61,15 +64,38 @@ PHP_FUNCTION(memcache_flush);
#define MMC_DEFAULT_TIMEOUT 1 /* seconds */
#define MMC_KEY_MAX_SIZE 250 /* stoled from memcached sources =) */
#define MMC_DEFAULT_PORT 11211
#define MMC_DEFAULT_RETRY 15 /* retry failed server after x seconds */
#define MMC_DEFAULT_SAVINGS 0.2 /* minimum 20% savings for compression to be used */
#define MMC_STATUS_DISCONNECTED 1
#define MMC_STATUS_CONNECTED 2
#define MMC_STATUS_UNKNOWN 3
#define MMC_STATUS_FAILED 4
typedef struct mmc {
int id;
php_stream *stream;
char inbuf[MMC_BUF_SIZE];
smart_str outbuf;
char *host;
unsigned short port;
long timeout;
long retry;
unsigned int retry_interval;
int persistent;
int status;
} mmc_t;
typedef struct mmc_pool {
int id;
mmc_t **servers;
int num_servers;
mmc_t **buckets;
int num_buckets;
mmc_t **requests;
int compress_threshold;
double min_compress_savings;
} mmc_pool_t;
/* our globals */
ZEND_BEGIN_MODULE_GLOBALS(memcache)
long debug_mode;

22
tests/018.phpt Normal file
View File

@@ -0,0 +1,22 @@
--TEST--
memcache_set() & memcache_add()
--SKIPIF--
<?php if(!extension_loaded("memcache")) print "skip"; ?>
--FILE--
<?php
include 'connect.inc';
$var = 'test';
error_reporting(E_ALL);
$result1 = memcache_set($memcache, 'non_existing_test_key', $var, false, 1);
$result2 = memcache_add($memcache, 'non_existing_test_key', $var, false, 1);
var_dump($result1);
var_dump($result2);
?>
--EXPECT--
bool(true)
bool(false)

25
tests/019.phpt Normal file
View File

@@ -0,0 +1,25 @@
--TEST--
memcache->addServer()
--SKIPIF--
<?php include 'connect.inc'; if(!extension_loaded("memcache") || !isset($host2)) print "skip"; ?>
--FILE--
<?php
include 'connect.inc';
$var = 'test';
$memcache = new Memcache();
$memcache->addServer($host, $port);
$memcache->addServer($host2, $port2, true, 1, 1, 15);
$result1 = $memcache->set('non_existing_test_key', $var, false, 1);
$result2 = $memcache->get('non_existing_test_key');
var_dump($result1);
var_dump($result2);
?>
--EXPECT--
bool(true)
string(4) "test"

51
tests/020.phpt Normal file
View File

@@ -0,0 +1,51 @@
--TEST--
memcache->set()/memcache->get() with multiple keys and load balancing
--SKIPIF--
<?php include 'connect.inc'; if(!extension_loaded("memcache") || !isset($host2)) print "skip"; ?>
--FILE--
<?php
include 'connect.inc';
$var1 = 'test1';
$var2 = 'test2';
$memcache = new Memcache();
$memcache->addServer($host, $port);
$memcache->addServer($host2, $port2);
$memcache1 = memcache_connect($host, $port, 1);
$memcache2 = memcache_pconnect($host2, $port2, 1);
$result1 = $memcache->set('load_test_key1', $var1, false, 1);
$result2 = $memcache->set('load_test_key2', $var2, false, 1);
$result3 = $memcache->get(array('load_test_key1','load_test_key2'));
var_dump($result1);
var_dump($result2);
var_dump($result3);
$result4 = $memcache1->get('load_test_key1');
$result5 = $memcache1->get('load_test_key2');
$result6 = $memcache2->get('load_test_key1');
$result7 = $memcache2->get('load_test_key2');
var_dump($result4);
var_dump($result5);
var_dump($result6);
var_dump($result7);
?>
--EXPECT--
bool(true)
bool(true)
array(2) {
["load_test_key1"]=>
string(5) "test1"
["load_test_key2"]=>
string(5) "test2"
}
bool(false)
string(5) "test2"
string(5) "test1"
bool(false)

48
tests/021.phpt Normal file
View File

@@ -0,0 +1,48 @@
--TEST--
memcache->set()/memcache->get() with failover
--SKIPIF--
<?php if(!extension_loaded("memcache")) print "skip"; ?>
--FILE--
<?php
include 'connect.inc';
$var1 = 'test1';
$var2 = 'test2';
$memcache = new Memcache();
$memcache->addServer($host, $port);
$memcache->addServer($nonExistingHost, $nonExistingPort);
$result1 = $memcache->set('load_test_key1', $var1, false, 1);
$result2 = $memcache->set('load_test_key2', $var2, false, 1);
$result3 = $memcache->get('load_test_key1');
$result4 = $memcache->get(array('load_test_key1','load_test_key2'));
var_dump($result1);
var_dump($result2);
var_dump($result3);
var_dump($result4);
$memcache = new Memcache();
$memcache->addServer($nonExistingHost, $nonExistingPort);
$result5 = @$memcache->set('load_test_key1', $var1, false, 1);
$result6 = @$memcache->get('load_test_key1');
var_dump($result5);
var_dump($result6);
?>
--EXPECT--
bool(true)
bool(true)
string(5) "test1"
array(2) {
["load_test_key1"]=>
string(5) "test1"
["load_test_key2"]=>
string(5) "test2"
}
bool(false)
bool(false)

31
tests/022.phpt Normal file
View File

@@ -0,0 +1,31 @@
--TEST--
memcache->getExtendedStats()
--SKIPIF--
<?php include 'connect.inc'; if(!extension_loaded("memcache") || !isset($host2)) print "skip"; ?>
--FILE--
<?php
include 'connect.inc';
$memcache = new Memcache();
$memcache->addServer($nonExistingHost, $nonExistingPort);
$memcache->addServer($host, $port);
$memcache->addServer($host2, $port2);
$result1 = @$memcache->getStats();
$result2 = @$memcache->getExtendedStats();
var_dump(count($result1));
var_dump(count($result2));
var_dump(count($result2["$host:$port"]));
var_dump(count($result2["$host2:$port2"]));
var_dump($result2["$nonExistingHost:$nonExistingPort"]);
?>
--EXPECT--
int(19)
int(3)
int(19)
int(19)
bool(false)

71
tests/023.phpt Normal file
View File

@@ -0,0 +1,71 @@
--TEST--
memcache->delete() with load balancing
--SKIPIF--
<?php include 'connect.inc'; if(!extension_loaded("memcache") || !isset($host2)) print "skip"; ?>
--FILE--
<?php
include 'connect.inc';
$var1 = 'test1';
$var2 = 'test2';
$memcache = new Memcache();
$memcache->addServer($host, $port);
$memcache->addServer($host2, $port2);
$memcache1 = memcache_connect($host, $port);
$memcache2 = memcache_connect($host2, $port2);
$result1 = $memcache->set('delete_test_key1', $var1, false, 1);
$result2 = $memcache->set('delete_test_key2', $var2, false, 1);
$result3 = $memcache->get('delete_test_key1');
$result4 = $memcache->get('delete_test_key2');
var_dump($result1);
var_dump($result2);
var_dump($result3);
var_dump($result4);
$result5 = $memcache1->get('delete_test_key1');
$result6 = $memcache1->get('delete_test_key2');
$result7 = $memcache2->get('delete_test_key1');
$result8 = $memcache2->get('delete_test_key2');
var_dump($result5);
var_dump($result6);
var_dump($result7);
var_dump($result8);
$result9 = $memcache->delete('delete_test_key1');
$result10 = $memcache->get('delete_test_key1');
$result11 = $memcache2->get('delete_test_key1');
var_dump($result9);
var_dump($result10);
var_dump($result11);
$result12 = $memcache->delete('delete_test_key2');
$result13 = $memcache->get('delete_test_key2');
$result14 = $memcache1->get('delete_test_key2');
var_dump($result12);
var_dump($result13);
var_dump($result14);
?>
--EXPECT--
bool(true)
bool(true)
string(5) "test1"
string(5) "test2"
string(5) "test1"
bool(false)
bool(false)
string(5) "test2"
bool(true)
bool(false)
bool(false)
bool(true)
bool(false)
bool(false)

35
tests/024.phpt Normal file
View File

@@ -0,0 +1,35 @@
--TEST--
memcache->close(), memcache->get()
--SKIPIF--
<?php include 'connect.inc'; if(!extension_loaded("memcache") || !isset($host2)) print "skip"; ?>
--FILE--
<?php
include 'connect.inc';
$memcache->addServer($host2, $port2);
$memcache->addServer($nonExistingHost, $nonExistingPort);
$result1 = $memcache->close();
var_dump($result1);
$memcache = new Memcache();
$result2 = $memcache->connect($host, $port);
$result3 = $memcache->set('non_existing_test_key', 'test', false, 1);
$result4 = $memcache->close();
// This additional get() will transparently reconnect
$result5 = $memcache->get('non_existing_test_key');
var_dump($result2);
var_dump($result3);
var_dump($result4);
var_dump($result5);
?>
--EXPECT--
bool(true)
bool(true)
bool(true)
bool(true)
string(4) "test"

49
tests/025.phpt Normal file
View File

@@ -0,0 +1,49 @@
--TEST--
memcache->increment() with load balancing
--SKIPIF--
<?php include 'connect.inc'; if(!extension_loaded("memcache") || !isset($host2)) print "skip"; ?>
--FILE--
<?php
include 'connect.inc';
$var1 = 10;
$var2 = 20;
$memcache = new Memcache();
$memcache->addServer($host, $port);
$memcache->addServer($host2, $port2);
$memcache1 = memcache_connect($host, $port);
$memcache2 = memcache_connect($host2, $port2);
$result1 = $memcache->set('increment_test_key1', $var1, false, 1);
$result2 = $memcache->set('increment_test_key2', $var2, false, 1);
$result3 = $memcache->increment('increment_test_key1');
$result4 = $memcache->increment('increment_test_key2');
var_dump($result1);
var_dump($result2);
var_dump($result3);
var_dump($result4);
$result5 = $memcache1->get('increment_test_key1');
$result6 = $memcache1->get('increment_test_key2');
$result7 = $memcache2->get('increment_test_key1');
$result8 = $memcache2->get('increment_test_key2');
var_dump($result5);
var_dump($result6);
var_dump($result7);
var_dump($result8);
?>
--EXPECT--
bool(true)
bool(true)
int(11)
int(21)
bool(false)
string(2) "21"
string(2) "11"
bool(false)

32
tests/026.phpt Normal file
View File

@@ -0,0 +1,32 @@
--TEST--
memcache->delete() with load balancing
--SKIPIF--
<?php include 'connect.inc'; if(!extension_loaded("memcache") || !isset($host2)) print "skip"; ?>
--FILE--
<?php
include 'connect.inc';
$var = 'test';
$memcache->addServer($host2, $port2);
$result1 = $memcache->set('delete_fail_key1', $var, false, 1);
$result2 = $memcache->delete('delete_fail_key1');
$result3 = $memcache->delete('delete_fail_key2');
var_dump($result1);
var_dump($result2);
var_dump($result3);
$memcache = new Memcache();
$memcache->addServer($nonExistingHost, $nonExistingPort);
$result4 = @$memcache->delete('delete_fail_key1');
var_dump($result4);
?>
--EXPECT--
bool(true)
bool(true)
bool(false)
bool(false)

40
tests/027.phpt Normal file
View File

@@ -0,0 +1,40 @@
--TEST--
memcache->setCompressThreshold()
--SKIPIF--
<?php if(!extension_loaded("memcache")) print "skip"; ?>
--FILE--
<?php
include 'connect.inc';
$var = str_repeat('abc', 5000);
$memcache->setCompressThreshold(10000);
$result1 = $memcache->set('non_existing_test_key', $var, 0, 1);
$result2 = $memcache->get('non_existing_test_key');
var_dump($result1);
var_dump(strlen($result2));
$memcache->setCompressThreshold(10000, 0);
$result3 = $memcache->set('non_existing_test_key', $var, 0, 1);
$memcache->setCompressThreshold(10000, 1);
$result4 = $memcache->set('non_existing_test_key', $var, 0, 1);
var_dump($result3);
var_dump($result4);
$result5 = $memcache->set('non_existing_test_key', 'abc', MEMCACHE_COMPRESSED, 1);
$result6 = $memcache->get('non_existing_test_key');
var_dump($result5);
var_dump($result6);
?>
--EXPECT--
bool(true)
int(15000)
bool(true)
bool(true)
bool(true)
string(3) "abc"

28
tests/028.phpt Normal file
View File

@@ -0,0 +1,28 @@
--TEST--
memcache->flush()
--SKIPIF--
<?php if(!extension_loaded("memcache")) print "skip"; ?>
--FILE--
<?php
// This test must be run last or some concurrency problems will occur
// since the "flush_all" seems to be done async and therefore will
// affect subsequent calls to set() done with a second or so.
include 'connect.inc';
$memcache->addServer($nonExistingHost, $nonExistingPort);
$result1 = @$memcache->flush();
var_dump($result1);
$memcache2 = new Memcache();
$memcache2->addServer($nonExistingHost, $nonExistingPort);
$result2 = @$memcache2->flush();
var_dump($result2);
?>
--EXPECT--
bool(true)
bool(false)

View File

@@ -7,6 +7,13 @@
$host = "localhost";
$port = 11211;
// Start an extra server and uncomment to enable load-balancing and failover tests
//$host2 = "localhost";
//$port2 = 11212;
$nonExistingHost = "localhost";
$nonExistingPort = 11213;
$memcache = memcache_connect($host, $port);
if (!$memcache) {