@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.

Track total time from task creation to task archival

Summary:
Ref T5401. Depends on D20201. Add timestamps to worker tasks to track task creation, and pass that through to archive tasks. This lets us measure the total time the task spent in the queue, not just the duration it was actually running.

Also displays this information in the daemon status console; see screenshot: {F6225726}

Test Plan:
Stopped daemons, ran `bin/search index --all --background` to create lots of tasks, restarted daemons, observed expected values for `dateCreated` and `epochArchived` in the archive worker table.

Also tested the changes to `unarchiveTask` by forcing a search task to permanently fail and then `bin/worker retry`ing it.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin, epriestley, PHID-OPKG-gm6ozazyms6q6i22gyam

Maniphest Tasks: T5401

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

+34 -4
+2
resources/sql/autopatches/20190220.daemon_worker.completed.01.sql
··· 1 + ALTER TABLE {$NAMESPACE}_worker.worker_archivetask 2 + ADD archivedEpoch INT UNSIGNED NULL;
+3
resources/sql/autopatches/20190220.daemon_worker.completed.02.sql
··· 1 + ALTER TABLE {$NAMESPACE}_worker.worker_activetask 2 + ADD dateCreated int unsigned NOT NULL, 3 + ADD dateModified int unsigned NOT NULL;
+23 -2
src/applications/daemon/controller/PhabricatorDaemonConsoleController.php
··· 31 31 $completed_info[$class] = array( 32 32 'n' => 0, 33 33 'duration' => 0, 34 + 'queueTime' => 0, 34 35 ); 35 36 } 36 37 $completed_info[$class]['n']++; ··· 41 42 // compute utilization. 42 43 $usage_total += $lease_overhead + ($duration / 1000000); 43 44 $usage_start = min($usage_start, $completed_task->getDateModified()); 45 + 46 + $date_archived = $completed_task->getArchivedEpoch(); 47 + $queue_seconds = $date_archived - $completed_task->getDateCreated(); 48 + 49 + // Don't measure queue time for tasks that completed in the same 50 + // epoch-second they were created in. 51 + if ($queue_seconds > 0) { 52 + $sec_in_us = phutil_units('1 second in microseconds'); 53 + $queue_us = $queue_seconds * $sec_in_us; 54 + $queue_exclusive_us = $queue_us - $duration; 55 + $queue_exclusive_seconds = $queue_exclusive_us / $sec_in_us; 56 + $rounded = floor($queue_exclusive_seconds); 57 + $completed_info[$class]['queueTime'] += $rounded; 58 + } 44 59 } 45 60 46 61 $completed_info = isort($completed_info, 'n'); 47 62 48 63 $rows = array(); 49 64 foreach ($completed_info as $class => $info) { 65 + $duration_avg = new PhutilNumber((int)($info['duration'] / $info['n'])); 66 + $queue_avg = new PhutilNumber((int)($info['queueTime'] / $info['n'])); 50 67 $rows[] = array( 51 68 $class, 52 69 number_format($info['n']), 53 - pht('%s us', new PhutilNumber((int)($info['duration'] / $info['n']))), 70 + pht('%s us', $duration_avg), 71 + pht('%s s', $queue_avg), 54 72 ); 55 73 } 56 74 ··· 98 116 phutil_tag('em', array(), pht('Queue Utilization (Approximate)')), 99 117 sprintf('%.1f%%', 100 * $used_time), 100 118 null, 119 + null, 101 120 ); 102 121 } 103 122 ··· 108 127 array( 109 128 pht('Class'), 110 129 pht('Count'), 111 - pht('Avg'), 130 + pht('Average Duration'), 131 + pht('Average Queue Time'), 112 132 )); 113 133 $completed_table->setColumnClasses( 114 134 array( 115 135 'wide', 136 + 'n', 116 137 'n', 117 138 'n', 118 139 ));
+3 -2
src/infrastructure/daemon/workers/storage/PhabricatorWorkerActiveTask.php
··· 12 12 13 13 $config = array( 14 14 self::CONFIG_IDS => self::IDS_COUNTER, 15 - self::CONFIG_TIMESTAMPS => false, 16 15 self::CONFIG_KEY_SCHEMA => array( 17 16 'taskClass' => array( 18 17 'columns' => array('taskClass'), ··· 118 117 ->setPriority($this->getPriority()) 119 118 ->setObjectPHID($this->getObjectPHID()) 120 119 ->setResult($result) 121 - ->setDuration($duration); 120 + ->setDuration($duration) 121 + ->setDateCreated($this->getDateCreated()) 122 + ->setArchivedEpoch(PhabricatorTime::getNow()); 122 123 123 124 // NOTE: This deletes the active task (this object)! 124 125 $archive->save();
+3
src/infrastructure/daemon/workers/storage/PhabricatorWorkerArchiveTask.php
··· 8 8 9 9 protected $duration; 10 10 protected $result; 11 + protected $archivedEpoch; 11 12 12 13 protected function getConfiguration() { 13 14 $parent = parent::getConfiguration(); ··· 22 23 $config[self::CONFIG_COLUMN_SCHEMA] = array( 23 24 'result' => 'uint32', 24 25 'duration' => 'uint64', 26 + 'archivedEpoch' => 'epoch?', 25 27 ) + $config[self::CONFIG_COLUMN_SCHEMA]; 26 28 27 29 $config[self::CONFIG_KEY_SCHEMA] = array( ··· 85 87 ->setDataID($this->getDataID()) 86 88 ->setPriority($this->getPriority()) 87 89 ->setObjectPHID($this->getObjectPHID()) 90 + ->setDateCreated($this->getDateCreated()) 88 91 ->insert(); 89 92 90 93 $this->setDataID(null);