public static function multiGetFromMemcached($mode, $items, array $queryParams) { $keys = array(); foreach ($items as $item) { $keys[] = self::getCacheKey($mode, $item, $queryParams); } $results = Z_Core::$MC->get($keys); $response = array(); if ($results) { foreach ($results as $key => $val) { $lk = self::extractLibraryKeyFromCacheKey($key); $response[$lk] = $val; } } $hits = sizeOf($results); $misses = sizeOf($items) - $hits; StatsD::updateStats("memcached.cite.{$mode}.hits", $hits); StatsD::updateStats("memcached.cite.{$mode}.misses", $misses); return $response; }
/** * Decrements one or more stats counters. * * @param string|array $stats The metric(s) to decrement. * @param float|1 $sampleRate the rate (0-1) for sampling. * @return boolean **/ public static function decrement($stats, $sampleRate = 1) { StatsD::updateStats($stats, -1, $sampleRate); }
public static function processUploadFromQueue($syncProcessID) { if (Z_Core::probability(30)) { $sql = "DELETE FROM syncProcesses WHERE started < (NOW() - INTERVAL 180 MINUTE)"; Zotero_DB::query($sql); } if (Z_Core::probability(30)) { $sql = "UPDATE syncUploadQueue SET started=NULL WHERE started IS NOT NULL AND errorCheck!=1 AND\n\t\t\t\t\t\tstarted < (NOW() - INTERVAL 12 MINUTE) AND finished IS NULL AND dataLength<250000"; Zotero_DB::query($sql); } if (Z_Core::probability(30)) { $sql = "UPDATE syncUploadQueue SET tries=0 WHERE started IS NULL AND\n\t\t\t\t\ttries>=5 AND finished IS NULL"; Zotero_DB::query($sql); } Zotero_DB::beginTransaction(); // Get a queued process $smallestFirst = Z_CONFIG::$SYNC_UPLOAD_SMALLEST_FIRST; $sortByQuota = !empty(Z_CONFIG::$SYNC_UPLOAD_SORT_BY_QUOTA); $sql = "SELECT syncUploadQueue.* FROM syncUploadQueue "; if ($sortByQuota) { $sql .= "LEFT JOIN storageAccounts USING (userID) "; } $sql .= "WHERE started IS NULL "; if (self::$minErrorCheckRequiredSize) { $sql .= "AND (errorCheck=2 OR dataLength<" . self::$minErrorCheckRequiredSize . ") "; } if ($smallestFirst && self::$maxSmallestSize) { $sql .= "AND dataLength<" . self::$maxSmallestSize . " "; } $sql .= "ORDER BY tries > 4, "; if ($sortByQuota) { $sql .= "quota DESC, "; } if ($smallestFirst) { //$sql .= "ROUND(dataLength / 1024 / 10), "; $sql .= "dataLength, "; } $sql .= "added LIMIT 1 FOR UPDATE"; $row = Zotero_DB::rowQuery($sql); // No pending processes if (!$row) { Zotero_DB::commit(); return 0; } $host = gethostbyname(gethostname()); $startedTimestamp = microtime(true); list($started, $startedMS) = self::getTimestampParts($startedTimestamp); $sql = "UPDATE syncUploadQueue SET started=FROM_UNIXTIME(?), processorHost=INET_ATON(?) WHERE syncUploadQueueID=?"; Zotero_DB::query($sql, array($started, $host, $row['syncUploadQueueID'])); Zotero_DB::commit(); Zotero_DB::close(); $processData = array("syncUploadQueueID" => $row['syncUploadQueueID'], "userID" => $row['userID'], "dataLength" => $row['dataLength']); Z_Core::$MC->set("syncUploadProcess_" . $syncProcessID, $processData, 86400); $error = false; $lockError = false; try { $xml = new SimpleXMLElement($row['xmldata'], LIBXML_COMPACT | LIBXML_PARSEHUGE); $timestamp = self::processUploadInternal($row['userID'], $xml, $row['syncUploadQueueID'], $syncProcessID); } catch (Exception $e) { $error = true; $code = $e->getCode(); $msg = $e->getMessage(); } Zotero_DB::beginTransaction(); // Mark upload as finished — NULL indicates success if (!$error) { $sql = "UPDATE syncUploadQueue SET finished=FROM_UNIXTIME(?) WHERE syncUploadQueueID=?"; Zotero_DB::query($sql, array($timestamp, $row['syncUploadQueueID'])); StatsD::increment("sync.process.upload.success"); StatsD::updateStats("sync.process.upload.size", $row['dataLength']); StatsD::timing("sync.process.upload.process", round((microtime(true) - $startedTimestamp) * 1000)); StatsD::timing("sync.process.upload.total", max(0, time() - strtotime($row['added'])) * 1000); try { $sql = "INSERT INTO syncUploadProcessLog\n\t\t\t\t\t\t(userID, dataLength, processorHost, processDuration, totalDuration, error)\n\t\t\t\t\t\tVALUES (?,?,INET_ATON(?),?,?,?)"; Zotero_DB::query($sql, array($row['userID'], $row['dataLength'], $host, round((double) microtime(true) - $startedTimestamp, 2), max(0, min(time() - strtotime($row['added']), 65535)), 0)); } catch (Exception $e) { Z_Core::logError($e); } try { self::processPostWriteLog($row['syncUploadQueueID'], $row['userID'], $timestamp); } catch (Exception $e) { Z_Core::logError($e); } } else { if (strpos($msg, "Lock wait timeout exceeded; try restarting transaction") !== false || strpos($msg, "Deadlock found when trying to get lock; try restarting transaction") !== false || strpos($msg, "Too many connections") !== false || strpos($msg, "Can't connect to MySQL server") !== false || strpos($msg, "Connection refused") !== false || strpos($msg, "Connection timed out") !== false || $code == Z_ERROR_LIBRARY_TIMESTAMP_ALREADY_USED || $code == Z_ERROR_SHARD_READ_ONLY || $code == Z_ERROR_SHARD_UNAVAILABLE) { Z_Core::logError($e); $sql = "UPDATE syncUploadQueue SET started=NULL, tries=tries+1 WHERE syncUploadQueueID=?"; Zotero_DB::query($sql, $row['syncUploadQueueID']); $lockError = true; StatsD::increment("sync.process.upload.errorTemporary"); } else { // As of PHP 5.3.2 we can't serialize objects containing SimpleXMLElements, // and since the stack trace includes one, we have to catch this and // manually reconstruct an exception $serialized = serialize(new Exception(iconv("utf-8", "utf-8//IGNORE", $msg), $e->getCode())); Z_Core::logError($e); $sql = "UPDATE syncUploadQueue SET finished=?, errorCode=?, errorMessage=? WHERE syncUploadQueueID=?"; Zotero_DB::query($sql, array(Zotero_DB::getTransactionTimestamp(), $e->getCode(), $serialized, $row['syncUploadQueueID'])); StatsD::increment("sync.process.upload.errorPermanent"); try { $sql = "INSERT INTO syncUploadProcessLog\n\t\t\t\t\t\t(userID, dataLength, processorHost, processDuration, totalDuration, error)\n\t\t\t\t\t\tVALUES (?,?,INET_ATON(?),?,?,?)"; Zotero_DB::query($sql, array($row['userID'], $row['dataLength'], $host, round((double) microtime(true) - $startedTimestamp, 2), max(0, min(time() - strtotime($row['added']), 65535)), 1)); } catch (Exception $e) { Z_Core::logError($e); } } } // Clear read locks $sql = "DELETE FROM syncUploadQueueLocks WHERE syncUploadQueueID=?"; Zotero_DB::query($sql, $row['syncUploadQueueID']); Zotero_DB::commit(); if ($lockError) { return -1; } else { if ($error) { return -2; } } return 1; }
/** * @todo Implement testUpdateStats(). */ public function testUpdateStats() { $this->statsd->updateStats("test.updateStat", "5", "1"); }