Esempio n. 1
0
 /**
  * Add sync process and associated locks to database
  */
 private static function addUploadProcess($userID, $libraryIDs, $syncQueueID = null, $syncProcessID = null)
 {
     Zotero_DB::beginTransaction();
     $syncProcessID = $syncProcessID ? $syncProcessID : Zotero_ID::getBigInt();
     $sql = "INSERT INTO syncProcesses (syncProcessID, userID) VALUES (?, ?)";
     try {
         Zotero_DB::query($sql, array($syncProcessID, $userID));
     } catch (Exception $e) {
         $sql = "SELECT CONCAT(syncProcessID,' ',userID,' ',started) FROM syncProcesses WHERE userID=?";
         $val = Zotero_DB::valueQuery($sql, $userID);
         Z_Core::logError($val);
     }
     if ($libraryIDs) {
         $sql = "INSERT INTO syncProcessLocks VALUES ";
         $sql .= implode(', ', array_fill(0, sizeOf($libraryIDs), '(?,?)'));
         $params = array();
         foreach ($libraryIDs as $libraryID) {
             $params[] = $syncProcessID;
             $params[] = $libraryID;
         }
         Zotero_DB::query($sql, $params);
     }
     // Record the process id in the queue entry, if given
     if ($syncQueueID) {
         $sql = "UPDATE syncUploadQueue SET syncProcessID=? WHERE syncUploadQueueID=?";
         Zotero_DB::query($sql, array($syncProcessID, $syncQueueID));
     }
     Zotero_DB::commit();
     return $syncProcessID;
 }
 public function run()
 {
     // Catch TERM and unregister from the database
     //pcntl_signal(SIGTERM, array($this, 'handleSignal'));
     //pcntl_signal(SIGINT, array($this, 'handleSignal'));
     $this->log("Starting " . $this->mode . " processor daemon");
     $this->register();
     // Bind
     $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
     $success = socket_bind($socket, $this->addr, $this->port);
     if (!$success) {
         $code = socket_last_error($socket);
         $this->unregister();
         die(socket_strerror($code));
     }
     $buffer = 'GO';
     $mode = null;
     $first = true;
     $lastPurge = 0;
     do {
         if ($first) {
             $first = false;
         } else {
             //$this->log("Waiting for command");
             $from = '';
             $port = 0;
             socket_recvfrom($socket, $buffer, 32, MSG_WAITALL, $from, $port);
         }
         //pcntl_signal_dispatch();
         // Processor return value
         if (preg_match('/^(DONE|NONE|LOCK|ERROR) ([0-9]+)/', $buffer, $return)) {
             $signal = $return[1];
             $id = $return[2];
             $this->removeProcessor($id);
             if ($signal == "DONE" || $signal == "ERROR") {
             } else {
                 if ($signal == "NONE") {
                     continue;
                 } else {
                     if ($signal == "LOCK") {
                         $this->log("LOCK received — waiting " . $this->lockWait . " second" . $this->pluralize($this->lockWait));
                         sleep($this->lockWait);
                     }
                 }
             }
             $buffer = "GO";
         }
         if ($buffer == "NEXT" || $buffer == "GO") {
             if ($lastPurge == 0) {
                 $lastPurge = microtime(true);
             } else {
                 if (microtime(true) - $lastPurge >= $this->minPurgeInterval) {
                     $purged = $this->purgeProcessors();
                     $this->log("Purged {$purged} lost processor" . $this->pluralize($purged));
                     $purged = $this->purgeOldProcesses();
                     $this->log("Purged {$purged} old process" . $this->pluralize($purged, "es"));
                     $lastPurge = microtime(true);
                 }
             }
             $numProcessors = $this->countProcessors();
             if ($numProcessors >= $this->maxProcessors) {
                 //$this->log("Already at max " . $this->maxProcessors . " processors");
                 continue;
             }
             try {
                 $queuedProcesses = $this->countQueuedProcesses();
                 $this->log($numProcessors . " processor" . $this->pluralize($numProcessors) . ", " . $queuedProcesses . " queued process" . $this->pluralize($queuedProcesses, "es"));
                 // Nothing queued, so go back and wait
                 if (!$queuedProcesses) {
                     continue;
                 }
                 // Wanna be startin' somethin'
                 $maxToStart = $this->maxProcessors - $numProcessors;
                 if ($queuedProcesses > $maxToStart) {
                     $toStart = $maxToStart;
                 } else {
                     $toStart = 1;
                 }
                 if ($toStart <= 0) {
                     $this->log("No processors to start");
                     continue;
                 }
                 $this->log("Starting {$toStart} new processor" . $this->pluralize($toStart));
                 // Start new processors
                 for ($i = 0; $i < $toStart; $i++) {
                     $id = Zotero_ID::getBigInt();
                     $pid = shell_exec(Z_CONFIG::$CLI_PHP_PATH . " " . Z_ENV_BASE_PATH . "processor/" . $this->mode . "/processor.php {$id} > /dev/null & echo \$!");
                     $this->processors[$id] = $pid;
                 }
             } catch (Exception $e) {
                 // If lost connection to MySQL, exit so we can be restarted
                 if (strpos($e->getMessage(), "MySQL error: MySQL server has gone away") === 0) {
                     $this->log($e);
                     $this->log("Lost connection to DB — exiting");
                     exit;
                 }
                 $this->log($e);
             }
         }
     } while ($buffer != 'QUIT');
     $this->log("QUIT received — exiting");
     $this->unregister();
 }