Page MenuHomePhabricator

D14178.id.diff
No OneTemporary

D14178.id.diff

diff --git a/src/applications/drydock/storage/DrydockLease.php b/src/applications/drydock/storage/DrydockLease.php
--- a/src/applications/drydock/storage/DrydockLease.php
+++ b/src/applications/drydock/storage/DrydockLease.php
@@ -334,10 +334,15 @@
),
array(
'objectPHID' => $this->getPHID(),
- 'delayUntil' => $epoch,
+ 'delayUntil' => ($epoch ? (int)$epoch : null),
));
}
+ public function setAwakenTaskIDs(array $ids) {
+ $this->setAttribute('internal.awakenTaskIDs', $ids);
+ return $this;
+ }
+
private function didActivate() {
$viewer = PhabricatorUser::getOmnipotentUser();
$need_update = false;
@@ -359,6 +364,11 @@
if ($expires) {
$this->scheduleUpdate($expires);
}
+
+ $awaken_ids = $this->getAttribute('internal.awakenTaskIDs');
+ if (is_array($awaken_ids) && $awaken_ids) {
+ PhabricatorWorker::awakenTaskIDs($awaken_ids);
+ }
}
diff --git a/src/applications/drydock/storage/DrydockResource.php b/src/applications/drydock/storage/DrydockResource.php
--- a/src/applications/drydock/storage/DrydockResource.php
+++ b/src/applications/drydock/storage/DrydockResource.php
@@ -218,7 +218,7 @@
),
array(
'objectPHID' => $this->getPHID(),
- 'delayUntil' => $epoch,
+ 'delayUntil' => ($epoch ? (int)$epoch : null),
));
}
diff --git a/src/applications/harbormaster/step/HarbormasterBuildStepImplementation.php b/src/applications/harbormaster/step/HarbormasterBuildStepImplementation.php
--- a/src/applications/harbormaster/step/HarbormasterBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/HarbormasterBuildStepImplementation.php
@@ -6,6 +6,16 @@
abstract class HarbormasterBuildStepImplementation extends Phobject {
private $settings;
+ private $currentWorkerTaskID;
+
+ public function setCurrentWorkerTaskID($id) {
+ $this->currentWorkerTaskID = $id;
+ return $this;
+ }
+
+ public function getCurrentWorkerTaskID() {
+ return $this->currentWorkerTaskID;
+ }
public static function getImplementations() {
return id(new PhutilClassMapQuery())
diff --git a/src/applications/harbormaster/step/HarbormasterLeaseWorkingCopyBuildStepImplementation.php b/src/applications/harbormaster/step/HarbormasterLeaseWorkingCopyBuildStepImplementation.php
--- a/src/applications/harbormaster/step/HarbormasterLeaseWorkingCopyBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/HarbormasterLeaseWorkingCopyBuildStepImplementation.php
@@ -54,6 +54,11 @@
->setAttribute('repositoryPHID', $repository_phid)
->setAttribute('commit', $commit);
+ $task_id = $this->getCurrentWorkerTaskID();
+ if ($task_id) {
+ $lease->setAwakenTaskIDs(array($task_id));
+ }
+
$lease->queueForActivation();
$build_target
diff --git a/src/applications/harbormaster/worker/HarbormasterTargetWorker.php b/src/applications/harbormaster/worker/HarbormasterTargetWorker.php
--- a/src/applications/harbormaster/worker/HarbormasterTargetWorker.php
+++ b/src/applications/harbormaster/worker/HarbormasterTargetWorker.php
@@ -59,6 +59,7 @@
}
$implementation = $target->getImplementation();
+ $implementation->setCurrentWorkerTaskID($this->getCurrentWorkerTaskID());
$implementation->execute($build, $target);
$next_status = HarbormasterBuildTarget::STATUS_PASSED;
diff --git a/src/infrastructure/daemon/workers/PhabricatorWorker.php b/src/infrastructure/daemon/workers/PhabricatorWorker.php
--- a/src/infrastructure/daemon/workers/PhabricatorWorker.php
+++ b/src/infrastructure/daemon/workers/PhabricatorWorker.php
@@ -8,6 +8,7 @@
private $data;
private static $runAllTasksInProcess = false;
private $queuedTasks = array();
+ private $currentWorkerTask;
// NOTE: Lower priority numbers execute first. The priority numbers have to
// have the same ordering that IDs do (lowest first) so MySQL can use a
@@ -18,6 +19,10 @@
const PRIORITY_BULK = 3000;
const PRIORITY_IMPORT = 4000;
+ /**
+ * Special owner indicating that the task has yielded.
+ */
+ const YIELD_OWNER = '(yield)';
/* -( Configuring Retries and Failures )----------------------------------- */
@@ -77,6 +82,23 @@
return null;
}
+ public function setCurrentWorkerTask(PhabricatorWorkerTask $task) {
+ $this->currentWorkerTask = $task;
+ return $this;
+ }
+
+ public function getCurrentWorkerTask() {
+ return $this->currentWorkerTask;
+ }
+
+ public function getCurrentWorkerTaskID() {
+ $task = $this->getCurrentWorkerTask();
+ if (!$task) {
+ return null;
+ }
+ return $task->getID();
+ }
+
abstract protected function doWork();
final public function __construct($data) {
@@ -105,6 +127,14 @@
$data,
$options = array()) {
+ PhutilTypeSpec::checkMap(
+ $options,
+ array(
+ 'priority' => 'optional int|null',
+ 'objectPHID' => 'optional string|null',
+ 'delayUntil' => 'optional int|null',
+ ));
+
$priority = idx($options, 'priority');
if ($priority === null) {
$priority = self::PRIORITY_DEFAULT;
@@ -208,4 +238,49 @@
return $this->queuedTasks;
}
+
+ /**
+ * Awaken tasks that have yielded.
+ *
+ * Reschedules the specified tasks if they are currently queued in a yielded,
+ * unleased, unretried state so they'll execute sooner. This can let the
+ * queue avoid unnecessary waits.
+ *
+ * This method does not provide any assurances about when these tasks will
+ * execute, or even guarantee that it will have any effect at all.
+ *
+ * @param list<id> List of task IDs to try to awaken.
+ * @return void
+ */
+ final public static function awakenTaskIDs(array $ids) {
+ if (!$ids) {
+ return;
+ }
+
+ $table = new PhabricatorWorkerActiveTask();
+ $conn_w = $table->establishConnection('w');
+
+ // NOTE: At least for now, we're keeping these tasks yielded, just
+ // pretending that they threw a shorter yield than they really did.
+
+ // Overlap the windows here to handle minor client/server time differences
+ // and because it's likely correct to push these tasks to the head of their
+ // respective priorities. There is a good chance they are ready to execute.
+ $window = phutil_units('1 hour in seconds');
+ $epoch_ago = (PhabricatorTime::getNow() - $window);
+
+ queryfx(
+ $conn_w,
+ 'UPDATE %T SET leaseExpires = %d
+ WHERE id IN (%Ld)
+ AND leaseOwner = %s
+ AND leaseExpires > %d
+ AND failureCount = 0',
+ $table->getTableName(),
+ $epoch_ago,
+ $ids,
+ self::YIELD_OWNER,
+ $epoch_ago);
+ }
+
}
diff --git a/src/infrastructure/daemon/workers/storage/PhabricatorWorkerActiveTask.php b/src/infrastructure/daemon/workers/storage/PhabricatorWorkerActiveTask.php
--- a/src/infrastructure/daemon/workers/storage/PhabricatorWorkerActiveTask.php
+++ b/src/infrastructure/daemon/workers/storage/PhabricatorWorkerActiveTask.php
@@ -141,6 +141,7 @@
$worker = null;
try {
$worker = $this->getWorkerInstance();
+ $worker->setCurrentWorkerTask($this);
$maximum_failures = $worker->getMaximumRetryCount();
if ($maximum_failures !== null) {
@@ -175,6 +176,8 @@
} catch (PhabricatorWorkerYieldException $ex) {
$this->setExecutionException($ex);
+ $this->setLeaseOwner(PhabricatorWorker::YIELD_OWNER);
+
$retry = $ex->getDuration();
$retry = max($retry, 5);

File Metadata

Mime Type
text/plain
Expires
Tue, Mar 25, 5:56 PM (1 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7388852
Default Alt Text
D14178.id.diff (7 KB)

Event Timeline