if ($fBucketVal > CONST_ConnectionBucket_WaitLimit && $fBucketVal < CONST_ConnectionBucket_BlockLimit)
{
- sleep(($fBucketVal - CONST_ConnectionBucket_WaitLimit)/CONST_ConnectionBucket_LeakRate);
- $fBucketVal = doBucket($aBucketKeys, 0, 0, CONST_ConnectionBucket_BlockLimit);
+ $m = getBucketMemcache();
+ $iCurrentSleeping = $m->increment('sleepCounter');
+ if (false === $iCurrentSleeping)
+ {
+ $m->add('sleepCounter', 0);
+ $iCurrentSleeping = $m->increment('sleepCounter');
+ }
+ if ($iCurrentSleeping >= CONST_ConnectionBucket_MaxSleeping)
+ {
+ // Too many threads sleeping already. This becomes a hard block.
+ $fBucketVal = doBucket($aBucketKeys, CONST_ConnectionBucket_BlockLimit, CONST_ConnectionBucket_LeakRate, CONST_ConnectionBucket_BlockLimit);
+ }
+ else
+ {
+ sleep(($fBucketVal - CONST_ConnectionBucket_WaitLimit)/CONST_ConnectionBucket_LeakRate);
+ $fBucketVal = doBucket($aBucketKeys, CONST_ConnectionBucket_LeakRate, CONST_ConnectionBucket_LeakRate, CONST_ConnectionBucket_BlockLimit);
+ }
+ $m->decrement('sleepCounter');
}
if (strpos(CONST_BlockedIPs, ','.$_SERVER["REMOTE_ADDR"].',') !== false || $fBucketVal >= CONST_ConnectionBucket_BlockLimit)
function getBucketMemcache()
{
+ static $m;
+
if (!CONST_ConnectionBucket_MemcacheServerAddress) return null;
- $m = new Memcached();
- $m->addServer(CONST_ConnectionBucket_MemcacheServerAddress, CONST_ConnectionBucket_MemcacheServerPort);
+ if (!isset($m))
+ {
+ $m = new Memcached();
+ $m->addServer(CONST_ConnectionBucket_MemcacheServerAddress, CONST_ConnectionBucket_MemcacheServerPort);
+ }
return $m;
}
@define('CONST_ConnectionBucket_LeakRate', 1);
@define('CONST_ConnectionBucket_BlockLimit', 10);
@define('CONST_ConnectionBucket_WaitLimit', 6);
+ @define('CONST_ConnectionBucket_MaxSleeping', 10);
@define('CONST_ConnectionBucket_Cost_Reverse', 1);
@define('CONST_ConnectionBucket_Cost_Search', 2);
@define('CONST_ConnectionBucket_Cost_Details', 3);
+ // Override this function to add an adjustment factor to the cost
+ // based on server load. e.g. getBlockingProcesses
if (!function_exists('user_busy_cost'))
{
function user_busy_cost()
if ($aResult['list'])
{
+ $iCurrentSleeping = $m->get('sleepCounter');
+ echo "\n Sleeping blocks count: $iCurrentSleeping\n";
+
$aBlocks = getBucketBlocks();
echo "\n";
printf(" %-40s | %12s | %7s | %13s | %16s | %31s\n", "Key", "Total Blocks", "Current", "Still Blocked", "Last Req Blocked", "Last Block Time");
if ($aResult['delete'])
{
+ $m->set('sleepCounter', 0);
clearBucketBlocks();
}