1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-27 09:12:41 +01:00

Queue large ICS files for background import

Summary: Ref T11801. When a file is larger than 512KB, queue it for background import instead of trying to do it in the foreground, sinc we risk hitting `max_execution_time`.

Test Plan: {F1906943}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T11801

Differential Revision: https://secure.phabricator.com/D16805
This commit is contained in:
epriestley 2016-11-06 07:36:25 -08:00
parent e1566bef63
commit 17bd483207
8 changed files with 108 additions and 9 deletions

View file

@ -2145,6 +2145,7 @@ phutil_register_library_map(array(
'PhabricatorCalendarImportOrphanLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportOrphanLogType.php', 'PhabricatorCalendarImportOrphanLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportOrphanLogType.php',
'PhabricatorCalendarImportPHIDType' => 'applications/calendar/phid/PhabricatorCalendarImportPHIDType.php', 'PhabricatorCalendarImportPHIDType' => 'applications/calendar/phid/PhabricatorCalendarImportPHIDType.php',
'PhabricatorCalendarImportQuery' => 'applications/calendar/query/PhabricatorCalendarImportQuery.php', 'PhabricatorCalendarImportQuery' => 'applications/calendar/query/PhabricatorCalendarImportQuery.php',
'PhabricatorCalendarImportQueueLogType' => 'applications/calendar/importlog/PhabricatorCalendarImportQueueLogType.php',
'PhabricatorCalendarImportReloadController' => 'applications/calendar/controller/PhabricatorCalendarImportReloadController.php', 'PhabricatorCalendarImportReloadController' => 'applications/calendar/controller/PhabricatorCalendarImportReloadController.php',
'PhabricatorCalendarImportReloadTransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportReloadTransaction.php', 'PhabricatorCalendarImportReloadTransaction' => 'applications/calendar/xaction/PhabricatorCalendarImportReloadTransaction.php',
'PhabricatorCalendarImportReloadWorker' => 'applications/calendar/worker/PhabricatorCalendarImportReloadWorker.php', 'PhabricatorCalendarImportReloadWorker' => 'applications/calendar/worker/PhabricatorCalendarImportReloadWorker.php',
@ -7012,6 +7013,7 @@ phutil_register_library_map(array(
'PhabricatorCalendarImportOrphanLogType' => 'PhabricatorCalendarImportLogType', 'PhabricatorCalendarImportOrphanLogType' => 'PhabricatorCalendarImportLogType',
'PhabricatorCalendarImportPHIDType' => 'PhabricatorPHIDType', 'PhabricatorCalendarImportPHIDType' => 'PhabricatorPHIDType',
'PhabricatorCalendarImportQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorCalendarImportQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorCalendarImportQueueLogType' => 'PhabricatorCalendarImportLogType',
'PhabricatorCalendarImportReloadController' => 'PhabricatorCalendarController', 'PhabricatorCalendarImportReloadController' => 'PhabricatorCalendarController',
'PhabricatorCalendarImportReloadTransaction' => 'PhabricatorCalendarImportTransactionType', 'PhabricatorCalendarImportReloadTransaction' => 'PhabricatorCalendarImportTransactionType',
'PhabricatorCalendarImportReloadWorker' => 'PhabricatorWorker', 'PhabricatorCalendarImportReloadWorker' => 'PhabricatorWorker',

View file

@ -54,7 +54,7 @@ final class PhabricatorCalendarImportEditor
if ($should_reload) { if ($should_reload) {
$import_engine = $object->getEngine(); $import_engine = $object->getEngine();
$import_engine->importEventsFromSource($actor, $object); $import_engine->importEventsFromSource($actor, $object, true);
} }
if ($should_trigger) { if ($should_trigger) {
@ -107,6 +107,7 @@ final class PhabricatorCalendarImportEditor
'class' => 'PhabricatorCalendarImportReloadWorker', 'class' => 'PhabricatorCalendarImportReloadWorker',
'data' => array( 'data' => array(
'importPHID' => $object->getPHID(), 'importPHID' => $object->getPHID(),
'via' => PhabricatorCalendarImportReloadWorker::VIA_TRIGGER,
), ),
'options' => array( 'options' => array(
'objectPHID' => $object->getPHID(), 'objectPHID' => $object->getPHID(),

View file

@ -65,7 +65,8 @@ final class PhabricatorCalendarICSFileImportEngine
public function importEventsFromSource( public function importEventsFromSource(
PhabricatorUser $viewer, PhabricatorUser $viewer,
PhabricatorCalendarImport $import) { PhabricatorCalendarImport $import,
$should_queue) {
$phid_key = PhabricatorCalendarImportICSFileTransaction::PARAMKEY_FILE; $phid_key = PhabricatorCalendarImportICSFileTransaction::PARAMKEY_FILE;
$file_phid = $import->getParameter($phid_key); $file_phid = $import->getParameter($phid_key);
@ -83,10 +84,13 @@ final class PhabricatorCalendarICSFileImportEngine
$data = $file->loadFileData(); $data = $file->loadFileData();
if ($should_queue && $this->shouldQueueDataImport($data)) {
return $this->queueDataImport($import, $data);
}
return $this->importICSData($viewer, $import, $data); return $this->importICSData($viewer, $import, $data);
} }
public function canDisable( public function canDisable(
PhabricatorUser $viewer, PhabricatorUser $viewer,
PhabricatorCalendarImport $import) { PhabricatorCalendarImport $import) {

View file

@ -77,7 +77,8 @@ final class PhabricatorCalendarICSURIImportEngine
public function importEventsFromSource( public function importEventsFromSource(
PhabricatorUser $viewer, PhabricatorUser $viewer,
PhabricatorCalendarImport $import) { PhabricatorCalendarImport $import,
$should_queue) {
$uri_key = PhabricatorCalendarImportICSURITransaction::PARAMKEY_URI; $uri_key = PhabricatorCalendarImportICSURITransaction::PARAMKEY_URI;
$uri = $import->getParameter($uri_key); $uri = $import->getParameter($uri_key);
@ -103,6 +104,10 @@ final class PhabricatorCalendarICSURIImportEngine
$data = $file->loadFileData(); $data = $file->loadFileData();
if ($should_queue && $this->shouldQueueDataImport($data)) {
return $this->queueDataImport($import, $data);
}
return $this->importICSData($viewer, $import, $data); return $this->importICSData($viewer, $import, $data);
} }

View file

@ -3,11 +3,12 @@
abstract class PhabricatorCalendarImportEngine abstract class PhabricatorCalendarImportEngine
extends Phobject { extends Phobject {
const QUEUE_BYTE_LIMIT = 524288;
final public function getImportEngineType() { final public function getImportEngineType() {
return $this->getPhobjectClassConstant('ENGINETYPE', 64); return $this->getPhobjectClassConstant('ENGINETYPE', 64);
} }
abstract public function getImportEngineName(); abstract public function getImportEngineName();
abstract public function getImportEngineTypeName(); abstract public function getImportEngineTypeName();
abstract public function getImportEngineHint(); abstract public function getImportEngineHint();
@ -27,7 +28,8 @@ abstract class PhabricatorCalendarImportEngine
abstract public function importEventsFromSource( abstract public function importEventsFromSource(
PhabricatorUser $viewer, PhabricatorUser $viewer,
PhabricatorCalendarImport $import); PhabricatorCalendarImport $import,
$should_queue);
abstract public function canDisable( abstract public function canDisable(
PhabricatorUser $viewer, PhabricatorUser $viewer,
@ -568,4 +570,35 @@ abstract class PhabricatorCalendarImportEngine
return (bool)$any_event; return (bool)$any_event;
} }
final protected function shouldQueueDataImport($data) {
return (strlen($data) > self::QUEUE_BYTE_LIMIT);
}
final protected function queueDataImport(
PhabricatorCalendarImport $import,
$data) {
$import->newLogMessage(
PhabricatorCalendarImportQueueLogType::LOGTYPE,
array(
'data.size' => strlen($data),
'data.limit' => self::QUEUE_BYTE_LIMIT,
));
// When we queue on this pathway, we're queueing in response to an explicit
// user action (like uploading a big `.ics` file), so we queue at normal
// priority instead of bulk/import priority.
PhabricatorWorker::scheduleTask(
'PhabricatorCalendarImportReloadWorker',
array(
'importPHID' => $import->getPHID(),
'via' => PhabricatorCalendarImportReloadWorker::VIA_BACKGROUND,
),
array(
'objectPHID' => $import->getPHID(),
));
}
} }

View file

@ -0,0 +1,40 @@
<?php
final class PhabricatorCalendarImportQueueLogType
extends PhabricatorCalendarImportLogType {
const LOGTYPE = 'queue';
public function getDisplayType(
PhabricatorUser $viewer,
PhabricatorCalendarImportLog $log) {
return pht('Queued');
}
public function getDisplayDescription(
PhabricatorUser $viewer,
PhabricatorCalendarImportLog $log) {
$size = $log->getParameter('data.size');
$limit = $log->getParameter('data.limit');
return pht(
'Queued for background import: data size (%s) exceeds limit for '.
'immediate processing (%s).',
phutil_format_bytes($size),
phutil_format_bytes($limit));
}
public function getDisplayIcon(
PhabricatorUser $viewer,
PhabricatorCalendarImportLog $log) {
return 'fa-sort-amount-desc';
}
public function getDisplayColor(
PhabricatorUser $viewer,
PhabricatorCalendarImportLog $log) {
return 'blue';
}
}

View file

@ -14,7 +14,15 @@ final class PhabricatorCalendarImportTriggerLogType
public function getDisplayDescription( public function getDisplayDescription(
PhabricatorUser $viewer, PhabricatorUser $viewer,
PhabricatorCalendarImportLog $log) { PhabricatorCalendarImportLog $log) {
return pht('Triggered a periodic update.');
$via = $log->getParameter('via');
switch ($via) {
case PhabricatorCalendarImportReloadWorker::VIA_BACKGROUND:
return pht('Started background processing.');
case PhabricatorCalendarImportReloadWorker::VIA_TRIGGER:
default:
return pht('Triggered a periodic update.');
}
} }
public function getDisplayIcon( public function getDisplayIcon(

View file

@ -2,6 +2,9 @@
final class PhabricatorCalendarImportReloadWorker extends PhabricatorWorker { final class PhabricatorCalendarImportReloadWorker extends PhabricatorWorker {
const VIA_TRIGGER = 'trigger';
const VIA_BACKGROUND = 'background';
protected function doWork() { protected function doWork() {
$import = $this->loadImport(); $import = $this->loadImport();
$viewer = PhabricatorUser::getOmnipotentUser(); $viewer = PhabricatorUser::getOmnipotentUser();
@ -18,11 +21,14 @@ final class PhabricatorCalendarImportReloadWorker extends PhabricatorWorker {
$import_engine = $import->getEngine(); $import_engine = $import->getEngine();
$data = $this->getTaskData();
$import->newLogMessage( $import->newLogMessage(
PhabricatorCalendarImportTriggerLogType::LOGTYPE, PhabricatorCalendarImportTriggerLogType::LOGTYPE,
array()); array(
'via' => idx($data, 'via', self::VIA_TRIGGER),
));
$import_engine->importEventsFromSource($author, $import); $import_engine->importEventsFromSource($author, $import, false);
} }
private function loadImport() { private function loadImport() {