@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Move completed tasks to an "archive" table and delete them in the GC

Summary:
Currently, when taskmasters complete a task it is immediately deleted. This prevents us from doing some general things, like:

- Supporting the idea of permanent failure (e.g., after N failures just stop trying).
- Showing the user how fast taskmasters are completing tasks.
- Showing the user how long tasks took to complete.

Having better visibility into this is important to Drydock, which builds on the task system. Also, generally buff debug output for task execution.

Test Plan: Ran `bin/phd debug taskmaster`. Ran `bin/phd debug garbage`. Queued some tasks via various systems.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2015

Differential Revision: https://secure.phabricator.com/D3852

+292 -102
+1
conf/default.conf.php
··· 1126 1126 'gcdaemon.ttl.daemon-logs' => 7 * (24 * 60 * 60), 1127 1127 'gcdaemon.ttl.differential-parse-cache' => 14 * (24 * 60 * 60), 1128 1128 'gcdaemon.ttl.markup-cache' => 30 * (24 * 60 * 60), 1129 + 'gcdaemon.ttl.task-archive' => 14 * (24 * 60 * 60), 1129 1130 1130 1131 1131 1132 // -- Feed ------------------------------------------------------------------ //
+13
resources/sql/patches/daemontaskarchive.sql
··· 1 + CREATE TABLE {$NAMESPACE}_worker.worker_archivetask ( 2 + id INT UNSIGNED PRIMARY KEY, 3 + taskClass VARCHAR(255) NOT NULL COLLATE utf8_bin, 4 + leaseOwner VARCHAR(255) COLLATE utf8_bin, 5 + leaseExpires INT UNSIGNED, 6 + failureCount INT UNSIGNED NOT NULL, 7 + dataID INT UNSIGNED NOT NULL, 8 + result INT UNSIGNED NOT NULL, 9 + duration BIGINT UNSIGNED NOT NULL, 10 + dateCreated INT UNSIGNED NOT NULL, 11 + dateModified INT UNSIGNED NOT NULL, 12 + key(dateCreated) 13 + ) ENGINE=InnoDB, COLLATE utf8_general_ci;
+3 -4
scripts/mail/create_worker_tasks.php
··· 33 33 34 34 foreach ($messages as $message) { 35 35 if (!$message->getWorkerTaskID()) { 36 - $mailer_task = new PhabricatorWorkerTask(); 37 - $mailer_task->setTaskClass('PhabricatorMetaMTAWorker'); 38 - $mailer_task->setData($message->getID()); 39 - $mailer_task->save(); 36 + $mailer_task = PhabricatorWorker::scheduleTask( 37 + 'PhabricatorMetaMTAWorker', 38 + $message->getID()); 40 39 41 40 $message->setWorkerTaskID($mailer_task->getID()); 42 41 $message->save();
+1 -4
scripts/repository/reparse.php
··· 224 224 225 225 if ($all_from_repo && !$force_local) { 226 226 foreach ($classes as $class) { 227 - $task = new PhabricatorWorkerTask(); 228 - $task->setTaskClass($class); 229 - $task->setData($spec); 230 - $task->save(); 227 + PhabricatorWorker::scheduleTask($class, $spec); 231 228 232 229 $commit_name = 'r'.$callsign.$commit->getCommitIdentifier(); 233 230 echo " Queued '{$class}' for commit '{$commit_name}'.\n";
+4
src/__phutil_library_map__.php
··· 1140 1140 'PhabricatorUserStatusOverlapException' => 'applications/people/exception/PhabricatorUserStatusOverlapException.php', 1141 1141 'PhabricatorUserTestCase' => 'applications/people/storage/__tests__/PhabricatorUserTestCase.php', 1142 1142 'PhabricatorWorker' => 'infrastructure/daemon/workers/PhabricatorWorker.php', 1143 + 'PhabricatorWorkerActiveTask' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerActiveTask.php', 1144 + 'PhabricatorWorkerArchiveTask' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerArchiveTask.php', 1143 1145 'PhabricatorWorkerDAO' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerDAO.php', 1144 1146 'PhabricatorWorkerTask' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerTask.php', 1145 1147 'PhabricatorWorkerTaskData' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerTaskData.php', ··· 2300 2302 'PhabricatorUserStatusInvalidEpochException' => 'Exception', 2301 2303 'PhabricatorUserStatusOverlapException' => 'Exception', 2302 2304 'PhabricatorUserTestCase' => 'PhabricatorTestCase', 2305 + 'PhabricatorWorkerActiveTask' => 'PhabricatorWorkerTask', 2306 + 'PhabricatorWorkerArchiveTask' => 'PhabricatorWorkerTask', 2303 2307 'PhabricatorWorkerDAO' => 'PhabricatorLiskDAO', 2304 2308 'PhabricatorWorkerTask' => 'PhabricatorWorkerDAO', 2305 2309 'PhabricatorWorkerTaskData' => 'PhabricatorWorkerDAO',
+2 -2
src/applications/daemon/controller/PhabricatorDaemonConsoleController.php
··· 34 34 $daemon_panel->setHeader('Recently Launched Daemons'); 35 35 $daemon_panel->appendChild($daemon_table); 36 36 37 - $tasks = id(new PhabricatorWorkerTask())->loadAllWhere( 37 + $tasks = id(new PhabricatorWorkerActiveTask())->loadAllWhere( 38 38 'leaseOwner IS NOT NULL'); 39 39 40 40 $rows = array(); ··· 80 80 $leased_panel->setHeader('Leased Tasks'); 81 81 $leased_panel->appendChild($leased_table); 82 82 83 - $task_table = new PhabricatorWorkerTask(); 83 + $task_table = new PhabricatorWorkerActiveTask(); 84 84 $queued = queryfx_all( 85 85 $task_table->establishConnection('r'), 86 86 'SELECT taskClass, count(*) N FROM %T GROUP BY taskClass
+1 -1
src/applications/daemon/controller/PhabricatorWorkerTaskDetailController.php
··· 29 29 $request = $this->getRequest(); 30 30 $user = $request->getUser(); 31 31 32 - $task = id(new PhabricatorWorkerTask())->load($this->id); 32 + $task = id(new PhabricatorWorkerActiveTask())->load($this->id); 33 33 if (!$task) { 34 34 $error_view = new AphrontErrorView(); 35 35 $error_view->setTitle('No Such Task');
+1 -1
src/applications/daemon/controller/PhabricatorWorkerTaskUpdateController.php
··· 31 31 $request = $this->getRequest(); 32 32 $user = $request->getUser(); 33 33 34 - $task = id(new PhabricatorWorkerTask())->load($this->id); 34 + $task = id(new PhabricatorWorkerActiveTask())->load($this->id); 35 35 if (!$task) { 36 36 return new Aphront404Response(); 37 37 }
+1 -4
src/applications/drydock/allocator/DrydockAllocator.php
··· 59 59 $worker = new DrydockAllocatorWorker($data); 60 60 $worker->executeTask(); 61 61 } else { 62 - $task = new PhabricatorWorkerTask(); 63 - $task->setTaskClass('DrydockAllocatorWorker'); 64 - $task->setData($data); 65 - $task->save(); 62 + PhabricatorWorker::scheduleTask('DrydockAllocatorWorker', $data); 66 63 } 67 64 68 65 return $lease;
+4 -4
src/applications/metamta/storage/PhabricatorMetaMTAMail.php
··· 298 298 parent::didWriteData(); 299 299 300 300 if (!$this->getWorkerTaskID()) { 301 - $mailer_task = new PhabricatorWorkerTask(); 302 - $mailer_task->setTaskClass('PhabricatorMetaMTAWorker'); 303 - $mailer_task->setData($this->getID()); 304 - $mailer_task->save(); 301 + $mailer_task = PhabricatorWorker::scheduleTask( 302 + 'PhabricatorMetaMTAWorker', 303 + $this->getID()); 304 + 305 305 $this->setWorkerTaskID($mailer_task->getID()); 306 306 $this->save(); 307 307 }
+1 -4
src/applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php
··· 450 450 throw new Exception("Unknown repository type '{$vcs}'!"); 451 451 } 452 452 453 - $task = new PhabricatorWorkerTask(); 454 - $task->setTaskClass($class); 455 453 $data['commitID'] = $commit->getID(); 456 454 457 - $task->setData($data); 458 - $task->save(); 455 + PhabricatorWorker::scheduleTask($class, $data); 459 456 } 460 457 461 458
+2 -4
src/applications/repository/worker/PhabricatorRepositoryCommitOwnersWorker.php
··· 73 73 } 74 74 75 75 if ($this->shouldQueueFollowupTasks()) { 76 - $herald_task = new PhabricatorWorkerTask(); 77 - $herald_task->setTaskClass('PhabricatorRepositoryCommitHeraldWorker'); 78 - $herald_task->setData( 76 + PhabricatorWorker::scheduleTask( 77 + 'PhabricatorRepositoryCommitHeraldWorker', 79 78 array( 80 79 'commitID' => $commit->getID(), 81 80 )); 82 - $herald_task->save(); 83 81 } 84 82 } 85 83
+2 -4
src/applications/repository/worker/commitchangeparser/PhabricatorRepositoryCommitChangeParserWorker.php
··· 76 76 PhabricatorSearchCommitIndexer::indexCommit($commit); 77 77 78 78 if ($this->shouldQueueFollowupTasks()) { 79 - $owner_task = new PhabricatorWorkerTask(); 80 - $owner_task->setTaskClass('PhabricatorRepositoryCommitOwnersWorker'); 81 - $owner_task->setData( 79 + PhabricatorWorker::scheduleTask( 80 + 'PhabricatorRepositoryCommitOwnersWorker', 82 81 array( 83 82 'commitID' => $commit->getID(), 84 83 )); 85 - $owner_task->save(); 86 84 } 87 85 } 88 86
+2 -4
src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryGitCommitMessageParserWorker.php
··· 69 69 $this->updateCommitData($author, $message, $committer); 70 70 71 71 if ($this->shouldQueueFollowupTasks()) { 72 - $task = new PhabricatorWorkerTask(); 73 - $task->setTaskClass('PhabricatorRepositoryGitCommitChangeParserWorker'); 74 - $task->setData( 72 + PhabricatorWorker::scheduleTask( 73 + 'PhabricatorRepositoryGitCommitChangeParserWorker', 75 74 array( 76 75 'commitID' => $commit->getID(), 77 76 )); 78 - $task->save(); 79 77 } 80 78 } 81 79
+2 -5
src/applications/repository/worker/commitmessageparser/PhabricatorRepositoryMercurialCommitMessageParserWorker.php
··· 37 37 $this->updateCommitData($author, $message); 38 38 39 39 if ($this->shouldQueueFollowupTasks()) { 40 - $task = new PhabricatorWorkerTask(); 41 - $task->setTaskClass( 42 - 'PhabricatorRepositoryMercurialCommitChangeParserWorker'); 43 - $task->setData( 40 + PhabricatorWorker::scheduleTask( 41 + 'PhabricatorRepositoryMercurialCommitChangeParserWorker', 44 42 array( 45 43 'commitID' => $commit->getID(), 46 44 )); 47 - $task->save(); 48 45 } 49 46 } 50 47
+2 -4
src/applications/repository/worker/commitmessageparser/PhabricatorRepositorySvnCommitMessageParserWorker.php
··· 38 38 $this->updateCommitData($author, $message); 39 39 40 40 if ($this->shouldQueueFollowupTasks()) { 41 - $task = new PhabricatorWorkerTask(); 42 - $task->setTaskClass('PhabricatorRepositorySvnCommitChangeParserWorker'); 43 - $task->setData( 41 + PhabricatorWorker::scheduleTask( 42 + 'PhabricatorRepositorySvnCommitChangeParserWorker', 44 43 array( 45 44 'commitID' => $commit->getID(), 46 45 )); 47 - $task->save(); 48 46 } 49 47 } 50 48
+44
src/infrastructure/daemon/PhabricatorGarbageCollectorDaemon.php
··· 64 64 $n_daemon = $this->collectDaemonLogs(); 65 65 $n_parse = $this->collectParseCaches(); 66 66 $n_markup = $this->collectMarkupCaches(); 67 + $n_tasks = $this->collectArchivedTasks(); 67 68 68 69 $collected = array( 69 70 'Herald Transcript' => $n_herald, 70 71 'Daemon Log' => $n_daemon, 71 72 'Differential Parse Cache' => $n_parse, 72 73 'Markup Cache' => $n_markup, 74 + 'Archived Tasks' => $n_tasks, 73 75 ); 74 76 $collected = array_filter($collected); 75 77 ··· 170 172 time() - $ttl); 171 173 172 174 return $conn_w->getAffectedRows(); 175 + } 176 + 177 + private function collectArchivedTasks() { 178 + $key = 'gcdaemon.ttl.task-archive'; 179 + $ttl = PhabricatorEnv::getEnvConfig($key); 180 + if ($ttl <= 0) { 181 + return 0; 182 + } 183 + 184 + $table = new PhabricatorWorkerArchiveTask(); 185 + $data_table = new PhabricatorWorkerTaskData(); 186 + $conn_w = $table->establishConnection('w'); 187 + 188 + $rows = queryfx_all( 189 + $conn_w, 190 + 'SELECT id, dataID FROM %T WHERE dateCreated < %d LIMIT 100', 191 + $table->getTableName(), 192 + time() - $ttl); 193 + 194 + if (!$rows) { 195 + return 0; 196 + } 197 + 198 + $data_ids = array_filter(ipull($rows, 'dataID')); 199 + $task_ids = ipull($rows, 'id'); 200 + 201 + $table->openTransaction(); 202 + if ($data_ids) { 203 + queryfx( 204 + $conn_w, 205 + 'DELETE FROM %T WHERE id IN (%Ld)', 206 + $data_table->getTableName(), 207 + $data_ids); 208 + } 209 + queryfx( 210 + $conn_w, 211 + 'DELETE FROM %T WHERE id IN (%Ld)', 212 + $table->getTableName(), 213 + $task_ids); 214 + $table->saveTransaction(); 215 + 216 + return count($task_ids); 173 217 } 174 218 175 219 }
+17 -10
src/infrastructure/daemon/workers/PhabricatorTaskmasterDaemon.php
··· 21 21 public function run() { 22 22 $lease_ownership_name = $this->getLeaseOwnershipName(); 23 23 24 - $task_table = new PhabricatorWorkerTask(); 24 + $task_table = new PhabricatorWorkerActiveTask(); 25 25 $taskdata_table = new PhabricatorWorkerTaskData(); 26 26 27 27 $sleep = 0; 28 28 do { 29 + $this->log('Dequeuing a task...'); 30 + 29 31 $conn_w = $task_table->establishConnection('w'); 30 32 queryfx( 31 33 $conn_w, ··· 36 38 $rows = $conn_w->getAffectedRows(); 37 39 38 40 if (!$rows) { 41 + $this->log('No unleased tasks. Dequeuing an expired lease...'); 39 42 queryfx( 40 43 $conn_w, 41 44 'UPDATE %T SET leaseOwner = %s, leaseExpires = UNIX_TIMESTAMP() + 15 ··· 70 73 } 71 74 72 75 foreach ($tasks as $task) { 76 + $id = $task->getID(); 77 + $class = $task->getTaskClass(); 78 + 79 + $this->log("Working on task {$id} ({$class})..."); 80 + 73 81 // TODO: We should detect if we acquired a task with an expired lease 74 82 // and log about it / bump up failure count. 75 83 ··· 77 85 // failure count and fail it permanently. 78 86 79 87 $data = idx($task_data, $task->getID()); 80 - $class = $task->getTaskClass(); 81 88 try { 82 89 if (!class_exists($class) || 83 90 !is_subclass_of($class, 'PhabricatorWorker')) { ··· 91 98 $task->setLeaseDuration($lease); 92 99 } 93 100 101 + $t_start = microtime(true); 94 102 $worker->executeTask(); 103 + $t_end = microtime(true); 95 104 96 - $task->delete(); 97 - if ($data !== null) { 98 - queryfx( 99 - $conn_w, 100 - 'DELETE FROM %T WHERE id = %d', 101 - $taskdata_table->getTableName(), 102 - $task->getDataID()); 103 - } 105 + $task->archiveTask( 106 + PhabricatorWorkerArchiveTask::RESULT_SUCCESS, 107 + (int)(1000000 * ($t_end - $t_start))); 108 + $this->log("Task {$id} complete! Moved to archive."); 104 109 } catch (Exception $ex) { 105 110 $task->setFailureCount($task->getFailureCount() + 1); 106 111 $task->save(); 112 + 113 + $this->log("Task {$id} failed!"); 107 114 throw $ex; 108 115 } 109 116 }
+9 -1
src/infrastructure/daemon/workers/PhabricatorWorker.php
··· 1 1 <?php 2 2 3 3 /* 4 - * Copyright 2011 Facebook, Inc. 4 + * Copyright 2012 Facebook, Inc. 5 5 * 6 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 7 * you may not use this file except in compliance with the License. ··· 37 37 } 38 38 39 39 abstract protected function doWork(); 40 + 41 + final public static function scheduleTask($task_class, $data) { 42 + return id(new PhabricatorWorkerActiveTask()) 43 + ->setTaskClass($task_class) 44 + ->setData($data) 45 + ->save(); 46 + } 47 + 40 48 }
+104
src/infrastructure/daemon/workers/storage/PhabricatorWorkerActiveTask.php
··· 1 + <?php 2 + 3 + /* 4 + * Copyright 2012 Facebook, Inc. 5 + * 6 + * Licensed under the Apache License, Version 2.0 (the "License"); 7 + * you may not use this file except in compliance with the License. 8 + * You may obtain a copy of the License at 9 + * 10 + * http://www.apache.org/licenses/LICENSE-2.0 11 + * 12 + * Unless required by applicable law or agreed to in writing, software 13 + * distributed under the License is distributed on an "AS IS" BASIS, 14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 + * See the License for the specific language governing permissions and 16 + * limitations under the License. 17 + */ 18 + 19 + final class PhabricatorWorkerActiveTask extends PhabricatorWorkerTask { 20 + 21 + private $serverTime; 22 + private $localTime; 23 + 24 + public function getTableName() { 25 + return 'worker_task'; 26 + } 27 + 28 + public function getConfiguration() { 29 + return array( 30 + self::CONFIG_TIMESTAMPS => false, 31 + ) + parent::getConfiguration(); 32 + } 33 + 34 + public function setServerTime($server_time) { 35 + $this->serverTime = $server_time; 36 + $this->localTime = time(); 37 + return $this; 38 + } 39 + 40 + public function setLeaseDuration($lease_duration) { 41 + $server_lease_expires = $this->serverTime + $lease_duration; 42 + $this->setLeaseExpires($server_lease_expires); 43 + return $this->save(); 44 + } 45 + 46 + public function save() { 47 + $this->checkLease(); 48 + 49 + $is_new = !$this->getID(); 50 + if ($is_new) { 51 + $this->failureCount = 0; 52 + } 53 + 54 + if ($is_new && $this->getData()) { 55 + $data = new PhabricatorWorkerTaskData(); 56 + $data->setData($this->getData()); 57 + $data->save(); 58 + 59 + $this->setDataID($data->getID()); 60 + } 61 + 62 + return parent::save(); 63 + } 64 + 65 + protected function checkLease() { 66 + if ($this->leaseOwner) { 67 + $current_server_time = $this->serverTime + (time() - $this->localTime); 68 + if ($current_server_time >= $this->leaseExpires) { 69 + throw new Exception("Trying to update task after lease expiration!"); 70 + } 71 + } 72 + } 73 + 74 + public function delete() { 75 + throw new Exception( 76 + "Active tasks can not be deleted directly. ". 77 + "Use archiveTask() to move tasks to the archive."); 78 + } 79 + 80 + public function archiveTask($result, $duration) { 81 + if (!$this->getID()) { 82 + throw new Exception( 83 + "Attempting to archive a task which hasn't been save()d!"); 84 + } 85 + 86 + $this->checkLease(); 87 + 88 + $archive = id(new PhabricatorWorkerArchiveTask()) 89 + ->setID($this->getID()) 90 + ->setTaskClass($this->getTaskClass()) 91 + ->setLeaseOwner($this->getLeaseOwner()) 92 + ->setLeaseExpires($this->getLeaseExpires()) 93 + ->setFailureCount($this->getFailureCount()) 94 + ->setDataID($this->getDataID()) 95 + ->setResult($result) 96 + ->setDuration($duration); 97 + 98 + // NOTE: This deletes the active task (this object)! 99 + $archive->save(); 100 + 101 + return $archive; 102 + } 103 + 104 + }
+66
src/infrastructure/daemon/workers/storage/PhabricatorWorkerArchiveTask.php
··· 1 + <?php 2 + 3 + /* 4 + * Copyright 2012 Facebook, Inc. 5 + * 6 + * Licensed under the Apache License, Version 2.0 (the "License"); 7 + * you may not use this file except in compliance with the License. 8 + * You may obtain a copy of the License at 9 + * 10 + * http://www.apache.org/licenses/LICENSE-2.0 11 + * 12 + * Unless required by applicable law or agreed to in writing, software 13 + * distributed under the License is distributed on an "AS IS" BASIS, 14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 + * See the License for the specific language governing permissions and 16 + * limitations under the License. 17 + */ 18 + 19 + final class PhabricatorWorkerArchiveTask extends PhabricatorWorkerTask { 20 + 21 + const RESULT_SUCCESS = 0; 22 + const RESULT_FAILURE = 1; 23 + 24 + protected $duration; 25 + protected $result; 26 + 27 + public function save() { 28 + if (!$this->getID()) { 29 + throw new Exception( 30 + "Trying to archive a task with no ID."); 31 + } 32 + 33 + $other = new PhabricatorWorkerActiveTask(); 34 + $conn_w = $this->establishConnection('w'); 35 + 36 + $this->openTransaction(); 37 + queryfx( 38 + $conn_w, 39 + 'DELETE FROM %T WHERE id = %d', 40 + $other->getTableName(), 41 + $this->getID()); 42 + $result = parent::insert(); 43 + $this->saveTransaction(); 44 + 45 + return $result; 46 + } 47 + 48 + public function delete() { 49 + $this->openTransaction(); 50 + if ($this->getDataID()) { 51 + $conn_w = $this->establishConnection('w'); 52 + $data_table = new PhabricatorWorkerTaskData(); 53 + 54 + queryfx( 55 + $conn_w, 56 + 'DELETE FROM %T WHERE id = %d', 57 + $data_table->getTableName(), 58 + $this->getDataID()); 59 + } 60 + 61 + $result = parent::delete(); 62 + $this->saveTransaction(); 63 + return $result; 64 + } 65 + 66 + }
+3 -1
src/infrastructure/daemon/workers/storage/PhabricatorWorkerDAO.php
··· 1 1 <?php 2 2 3 3 /* 4 - * Copyright 2011 Facebook, Inc. 4 + * Copyright 2012 Facebook, Inc. 5 5 * 6 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 7 * you may not use this file except in compliance with the License. ··· 17 17 */ 18 18 19 19 abstract class PhabricatorWorkerDAO extends PhabricatorLiskDAO { 20 + 20 21 public function getApplicationName() { 21 22 return 'worker'; 22 23 } 24 + 23 25 }
+3 -45
src/infrastructure/daemon/workers/storage/PhabricatorWorkerTask.php
··· 16 16 * limitations under the License. 17 17 */ 18 18 19 - final class PhabricatorWorkerTask extends PhabricatorWorkerDAO { 19 + abstract class PhabricatorWorkerTask extends PhabricatorWorkerDAO { 20 20 21 + // NOTE: If you provide additional fields here, make sure they are handled 22 + // correctly in the archiving process. 21 23 protected $taskClass; 22 24 protected $leaseOwner; 23 25 protected $leaseExpires; 24 26 protected $failureCount; 25 27 protected $dataID; 26 28 27 - private $serverTime; 28 - private $localTime; 29 29 private $data; 30 - 31 - public function getConfiguration() { 32 - return array( 33 - self::CONFIG_TIMESTAMPS => false, 34 - ) + parent::getConfiguration(); 35 - } 36 - 37 - public function setServerTime($server_time) { 38 - $this->serverTime = $server_time; 39 - $this->localTime = time(); 40 - return $this; 41 - } 42 - 43 - public function setLeaseDuration($lease_duration) { 44 - $server_lease_expires = $this->serverTime + $lease_duration; 45 - $this->setLeaseExpires($server_lease_expires); 46 - return $this->save(); 47 - } 48 - 49 - public function save() { 50 - if ($this->leaseOwner) { 51 - $current_server_time = $this->serverTime + (time() - $this->localTime); 52 - if ($current_server_time >= $this->leaseExpires) { 53 - throw new Exception("Trying to update task after lease expiration!"); 54 - } 55 - } 56 - 57 - $is_new = !$this->getID(); 58 - if ($is_new) { 59 - $this->failureCount = 0; 60 - } 61 - 62 - if ($is_new && $this->data) { 63 - $data = new PhabricatorWorkerTaskData(); 64 - $data->setData($this->data); 65 - $data->save(); 66 - 67 - $this->setDataID($data->getID()); 68 - } 69 - 70 - return parent::save(); 71 - } 72 30 73 31 public function setData($data) { 74 32 $this->data = $data;
+4
src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
··· 1016 1016 'type' => 'sql', 1017 1017 'name' => $this->getPatchPath('statustxt.sql'), 1018 1018 ), 1019 + 'daemontaskarchive.sql' => array( 1020 + 'type' => 'sql', 1021 + 'name' => $this->getPatchPath('daemontaskarchive.sql'), 1022 + ), 1019 1023 ); 1020 1024 } 1021 1025