Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15388675
D15378.id37073.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Referenced Files
None
Subscribers
None
D15378.id37073.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1045,6 +1045,7 @@
'HarbormasterBuildLintMessage' => 'applications/harbormaster/storage/build/HarbormasterBuildLintMessage.php',
'HarbormasterBuildLog' => 'applications/harbormaster/storage/build/HarbormasterBuildLog.php',
'HarbormasterBuildLogChunk' => 'applications/harbormaster/storage/build/HarbormasterBuildLogChunk.php',
+ 'HarbormasterBuildLogChunkIterator' => 'applications/harbormaster/storage/build/HarbormasterBuildLogChunkIterator.php',
'HarbormasterBuildLogPHIDType' => 'applications/harbormaster/phid/HarbormasterBuildLogPHIDType.php',
'HarbormasterBuildLogQuery' => 'applications/harbormaster/query/HarbormasterBuildLogQuery.php',
'HarbormasterBuildMessage' => 'applications/harbormaster/storage/HarbormasterBuildMessage.php',
@@ -5192,6 +5193,7 @@
'PhabricatorPolicyInterface',
),
'HarbormasterBuildLogChunk' => 'HarbormasterDAO',
+ 'HarbormasterBuildLogChunkIterator' => 'PhutilBufferedIterator',
'HarbormasterBuildLogPHIDType' => 'PhabricatorPHIDType',
'HarbormasterBuildLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'HarbormasterBuildMessage' => array(
diff --git a/src/applications/harbormaster/storage/build/HarbormasterBuildLog.php b/src/applications/harbormaster/storage/build/HarbormasterBuildLog.php
--- a/src/applications/harbormaster/storage/build/HarbormasterBuildLog.php
+++ b/src/applications/harbormaster/storage/build/HarbormasterBuildLog.php
@@ -16,11 +16,6 @@
const CHUNK_BYTE_LIMIT = 102400;
- /**
- * The log is encoded as plain text.
- */
- const ENCODING_TEXT = 'text';
-
public function __construct() {
$this->rope = new PhutilRope();
}
@@ -129,6 +124,8 @@
$chunk_table = id(new HarbormasterBuildLogChunk())->getTableName();
$chunk_limit = self::CHUNK_BYTE_LIMIT;
+ $encoding_text = HarbormasterBuildLogChunk::CHUNK_ENCODING_TEXT;
+
$rope = $this->rope;
while (true) {
@@ -147,7 +144,7 @@
$can_append =
($tail) &&
- ($tail['encoding'] == self::ENCODING_TEXT) &&
+ ($tail['encoding'] == $encoding_text) &&
($tail['size'] < $chunk_limit);
if ($can_append) {
$append_id = $tail['id'];
@@ -176,7 +173,7 @@
VALUES (%d, %s, %d, %B)',
$chunk_table,
$this->getID(),
- self::ENCODING_TEXT,
+ $encoding_text,
$data_size,
$append_data);
}
@@ -185,29 +182,21 @@
}
}
+ public function newChunkIterator() {
+ return new HarbormasterBuildLogChunkIterator($this);
+ }
+
public function getLogText() {
- // TODO: This won't cope very well if we're pulling like a 700MB
- // log file out of the DB. We should probably implement some sort
- // of optional limit parameter so that when we're rendering out only
- // 25 lines in the UI, we don't wastefully read in the whole log.
-
- // We have to read our content out of the database and stitch all of
- // the log data back together.
- $conn = $this->establishConnection('r');
- $result = queryfx_all(
- $conn,
- 'SELECT chunk '.
- 'FROM %T '.
- 'WHERE logID = %d '.
- 'ORDER BY id ASC',
- id(new HarbormasterBuildLogChunk())->getTableName(),
- $this->getID());
-
- $content = '';
- foreach ($result as $row) {
- $content .= $row['chunk'];
+ // TODO: Remove this method since it won't scale for big logs.
+
+ $all_chunks = $this->newChunkIterator();
+
+ $full_text = array();
+ foreach ($all_chunks as $chunk) {
+ $full_text[] = $chunk->getChunkDisplayText();
}
- return $content;
+
+ return implode('', $full_text);
}
diff --git a/src/applications/harbormaster/storage/build/HarbormasterBuildLogChunk.php b/src/applications/harbormaster/storage/build/HarbormasterBuildLogChunk.php
--- a/src/applications/harbormaster/storage/build/HarbormasterBuildLogChunk.php
+++ b/src/applications/harbormaster/storage/build/HarbormasterBuildLogChunk.php
@@ -8,6 +8,12 @@
protected $size;
protected $chunk;
+
+ /**
+ * The log is encoded as plain text.
+ */
+ const CHUNK_ENCODING_TEXT = 'text';
+
protected function getConfiguration() {
return array(
self::CONFIG_TIMESTAMPS => false,
@@ -29,4 +35,21 @@
) + parent::getConfiguration();
}
+ public function getChunkDisplayText() {
+ $data = $this->getChunk();
+ $encoding = $this->getEncoding();
+
+ switch ($encoding) {
+ case self::CHUNK_ENCODING_TEXT:
+ // Do nothing, data is already plaintext.
+ break;
+ default:
+ throw new Exception(
+ pht('Unknown log chunk encoding ("%s")!', $encoding));
+ }
+
+ return $data;
+ }
+
+
}
diff --git a/src/applications/harbormaster/storage/build/HarbormasterBuildLogChunkIterator.php b/src/applications/harbormaster/storage/build/HarbormasterBuildLogChunkIterator.php
new file mode 100644
--- /dev/null
+++ b/src/applications/harbormaster/storage/build/HarbormasterBuildLogChunkIterator.php
@@ -0,0 +1,35 @@
+<?php
+
+final class HarbormasterBuildLogChunkIterator
+ extends PhutilBufferedIterator {
+
+ private $log;
+ private $cursor;
+
+ public function __construct(HarbormasterBuildLog $log) {
+ $this->log = $log;
+ }
+
+ protected function didRewind() {
+ $this->cursor = 0;
+ }
+
+ public function key() {
+ return $this->current()->getID();
+ }
+
+ protected function loadPage() {
+ $results = id(new HarbormasterBuildLogChunk())->loadAllWhere(
+ 'logID = %d AND id > %d ORDER BY id ASC LIMIT %d',
+ $this->log->getID(),
+ $this->cursor,
+ $this->getPageSize());
+
+ if ($results) {
+ $this->cursor = last($results)->getID();
+ }
+
+ return $results;
+ }
+
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Mar 16, 4:14 AM (5 d, 18 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7705692
Default Alt Text
D15378.id37073.diff (5 KB)
Attached To
Mode
D15378: Implement an iterator for build log chunks
Attached
Detach File
Event Timeline
Log In to Comment