Example #1
0
 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;
 }
Example #2
0
 /**
  * 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);
 }
Example #3
0
 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;
 }
Example #4
0
 /**
  * @todo Implement testUpdateStats().
  */
 public function testUpdateStats()
 {
     $this->statsd->updateStats("test.updateStat", "5", "1");
 }