static function store_clicks() { global $globals, $db; if (!self::$clicked) { return false; } $id = self::$clicked; self::$clicked = 0; if (!memcache_menabled()) { $db->query("UPDATE link_clicks SET counter=counter+1 WHERE id = {$id}"); return true; } $key = 'clicks_cache'; $cache = memcache_mget($key); if (!$cache || !is_array($cache)) { $cache = array(); $cache['time'] = $globals['start_time']; $cache[$id] = 1; $in_cache = false; } else { $cache[$id]++; $in_cache = true; } if ($globals['start_time'] - $cache['time'] > 3.0 + rand(0, 100) / 100) { // We use random to minimize race conditions for deleting the cache if ($in_cache && !memcache_mdelete($key)) { memcache_madd($key, array()); syslog(LOG_INFO, "store_clicks: Delete failed"); } ksort($cache); // To avoid transaction's deadlocks $show_errors = $db->show_errors; $db->show_errors = false; // we know there can be lock timeouts :( $tries = 0; // By the way, freaking locking timeouts with few updates per second with this technique while ($tries < 3) { $error = false; $db->transaction(); $total = 0; $r = true; foreach ($cache as $id => $counter) { if ($id > 0 && $counter > 0) { $r = $db->query("INSERT INTO link_clicks (id, counter) VALUES ({$id},{$counter}) ON DUPLICATE KEY UPDATE counter=counter+{$counter}"); // $r = $db->query("UPDATE link_clicks SET counter=counter+$counter WHERE id = $id"); if (!$r) { break; } $total += $counter; } } if ($r) { $db->commit(); $tries = 100000; // Stop it } else { $tries++; syslog(LOG_INFO, "failed {$tries} attempts in store_clicks"); $db->rollback(); } } $db->show_errors = $show_errors; } else { memcache_madd($key, $cache); } }
if (empty($globals['maintenance'])) { // Check cache dir if (!is_dir($globals['cache_dir'])) { ping_error('cache directory not available'); } if (!is_writeable($globals['cache_dir'])) { ping_error('cache directory not writeble'); } // Check access to DB $db->connect(); if (!$db->connected) { // Force DB access ping_error('DB not available'); } // Check memcache if (memcache_menabled()) { $data = array(1, 2, 3); memcache_madd('ping', $data, 10); $result = memcache_mget('ping'); if (!$result || $data != $result) { ping_error('memcache failed'); } } } echo "pong\n"; function ping_error($log) { header('HTTP/1.1 500 Server error'); if (!empty($log)) { echo "ERROR ping: {$log}"; syslog(LOG_INFO, "ERROR ping: {$log}");